这是我实际拥有的一些代码的最小测试用例.它在尝试评估时失败a.getResult<B>():
test.cpp: In function 'void printStuff(const A&)':
test.cpp:6: error: expected primary-expression before '>' token
test.cpp:6: error: expected primary-expression before ')' token
Run Code Online (Sandbox Code Playgroud)
代码是:
#include <iostream>
template< class A, class B>
void printStuff( const A& a)
{
size_t value = a.getResult<B>();
std::cout << value << std::endl;
}
struct Firstclass {
template< class X >
size_t getResult() const {
X someInstance;
return sizeof(someInstance);
}
};
int main(int, char**) {
Firstclass foo;
printStuff<Firstclass, short int>(foo);
printStuff<Firstclass, double>(foo);
std::cout << foo.getResult< double >() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我注释掉printStuff函数及其调用位置,则foo.getResult< double >()调用编译良好并执行预期的操作.
知道发生了什么事吗?我一直在使用广泛模板化的代码,从未遇到过这样的事情.
AnT*_*AnT 40
当您引用属于依赖类型的成员的模板时,必须在其前面加上关键字template.这就是对getResult内部的调用printStuff应该如何看待
size_t value = a.template getResult<B>();
Run Code Online (Sandbox Code Playgroud)
这类似于typename在引用依赖类型中的嵌套类型名时使用关键字.出于某种原因,关于typename嵌套类型的一点是众所周知的,但是对于template嵌套模板的类似要求是相对未知的.
请注意,一般语法结构虽然有点不同.将typename始终放在类型的全名的前面,而template插在中间.
同样,只有在访问依赖类型的模板成员时才需要这样做,在上面的示例中,该模板成员将A在其中printStuff.当你调用foo.getResult<>中main的类型foo不依赖,因此没有必要包含template关键字.
根据C++标准14.2/4,您的代码格式不正确:
当一个构件模板特的名称出现之后
.或->在一个后缀表达式,或之后嵌套名称说明符在一个合格-ID,和后缀表达或合格-ID明确地依赖于模板参数(14.6.2 ),成员模板名称必须以关键字为前缀template.否则,假定该名称命名非模板.
所以,你应该写 size_t value = a.template getResult<B>();