可能重复:
Templates: template function not playing well with class’s template member function
template <typename T>
struct A
{
template <int I>
void f();
};
template <typename T>
void F(A<T> &a)
{
a.f<0>(); // expected primary-expression before ‘)’ token
}
int main()
{
A<int> a;
a.f<0>(); // This one is ok.
}
它的全部意义?
答案 0 :(得分:16)
当使用依赖名称来引用嵌套模板时,必须在嵌套名称前加上关键字template
,以帮助编译器理解您所指的是嵌套模板并正确解析代码
template <typename T>
void F(A<T> &a)
{
a.template f<0>();
}
在main
内,名称a
不依赖,这就是您不需要额外的template
关键字的原因。内部F
名称a
是依赖的,这就是需要关键字的原因。
当通过依赖名称引用嵌套类型名称时,这类似于额外的typename
关键字。只是语法略有不同。
答案 1 :(得分:1)
在前者中,编译器认为你的意思是......
a.f < 0 ...gibberish....
安德烈的回答解决了这个问题。
答案 2 :(得分:0)
请注意,是代码段,对 添加的关键字和不添加有效,在每种情况下产生不同的结果,甚至对于采用类型参数而不是整数的模板。
#include <iostream>
struct A {
template<typename T>
static A f(T) {
return A();
}
template<typename T> operator T() { return T(); }
};
template<typename U>
int g() {
U u;
typedef A (*funcPtrType)(int());
return !(funcPtrType)u.f < int() > (0);
}
int main() {
std::cout << g<A>() << std::endl;
}
在未添加0
关键字的情况下运行时输出template
。如果您在f < int() >
之前添加关键字,则会输出1
。
<强>解释强>
没有关键字的版本解析为
funcPtrType temp1 = (funcPtrType)u.f; // taking func address
bool temp2 = !temp1; // temp2 == false
bool temp3 = temp2 < int(); // temp3 == false
bool temp4 = temp3 > (0); // temp4 == false
return temp4;
带有关键字的版本解析为
A temp1 = u.template f < int() > (0); // function call
funcPtrType temp2 = (funcPtrType) temp1; // temp2 == 0
bool temp3 = !temp2; // temp3 == true
return temp3;
请注意temp2
是一个空指针(由return T()
生成)。整个不同的解析,都是有效的!这确实需要一种消除歧义的方法 - 即在适当时插入template
关键字。