使用模板参数的静态成员模板
Using static member templates of a template parameter
为什么不编译此代码?
struct A {
template <class T>
static T a(int i) { return 2*i; }
};
template <class T>
struct B {
double b;
B(): b(T::a<double>(5)) {}
};
template class B<A>;
编译器甚至没有达到模板实例化。我使用的是gcc 4.7.0。
test.cc: In constructor »B<T>::B()«:
test.cc:9:25: Error: expected »(« before »<« token
test.cc:9:26: Error: expected primary-expression before »double«
您缺少一个template
关键字,因为a
是一个依赖名称(或类似名称)。
B(): b(T::template a<double>(5)) {}
(最后一行应该是template struct B<A>;
。)
有关血腥的详细信息,请参阅:我必须把";模板";以及";typename";关键词?
您必须将template
放在方法名称之前:
B(): b(T::template a<double>(5)) {}
这是因为在解析模板类B
时,编译器不知道T::a
是一个模板化方法(因为在此之前没有指定T
,而T::a
是完全未知的),所以它不知道应该将<double>
解析为模板参数列表。
它也可能意味着并且确实将被解析为:T::a
小于double
大于(0)
。当然,double
不是一个表达式,所以它失败了;从而产生错误消息。因此,编译器可以假设您希望它是一个模板化的函数调用。但是你也可以有一个非类型的模板参数,比如说一个int,所以T::a<42>(5)
可以被解析为T::a
小于42
大于(5)
,这不是一个模板。但您希望它被解析为T::a
,然后是带有参数42
的模板参数列表,然后是带参数5
的调用运算符。
要告诉编译器这是一个模板化的函数调用,必须将template
放在函数名之前。
编译器对T一无所知。因此,每次编写T::{something}
时,它都假设{something}
是T的成员变量或方法。如果不是,你必须告诉它它是什么。如果你所指的是类型而不是变量,你可能知道必须使用的typename
关键字。模板成员也有类似的技巧:
template <class T>
struct B {
double b;
B(): b(T::template a<double>(5)) {}
};
现在编译器知道a
是一个模板,然后是模板参数列表。
相关文章:
- 用作默认参数的静态成员会导致无法解析的外部
- 在没有对象参数编译器错误的情况下调用非静态成员函数
- 私有静态成员可以用作其类的成员函数的默认参数吗
- boost::信号与来自静态成员函数的参数
- 不接受静态成员函数作为 constexpr 参数
- 静态成员函数指针作为模板参数
- 如何用功能指针作为参数初始化静态成员的模板
- 使用相同的参数重构静态成员函数
- 默认参数:在非静态成员函数之外无效使用'this'
- C++11:在类构造函数中使用非静态成员函数作为默认参数
- 如何初始化参数化模板类的静态成员
- 定义静态成员的默认参数
- 具有非类型参数的类模板的静态成员的 gdb "static field value has been optimized out"
- 调用非静态成员函数,没有对象参数错误
- 指向静态成员函数的指针"invalid"为 G++ 的模板参数
- 编译器是否足够聪明,可以优化成员与静态方法参数相同的函子
- 初始化使用模板参数作为类型的模板化类的静态成员?
- c++错误:调用没有对象参数的非静态成员函数
- C++通过将静态成员变量作为参数传递来初始化该变量
- 将静态成员函数作为参数传递