这是我实际拥有的一些代码的最小测试用例。它在尝试评估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
代码是:
#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;
}
如果我注释掉printStuff
函数及其调用位置,则foo.getResult< double >()
调用编译正常并执行预期的操作。
知道发生了什么事吗?我一直在使用广泛模板化的代码,从未遇到过这样的事情。
答案 0 :(得分:39)
当您引用属于依赖类型的成员的模板时,您必须在其前面添加关键字template
。这是getResult
printStuff
内size_t value = a.template getResult<B>();
的调用
typename
这类似于在引用依赖类型中的嵌套类型名时使用关键字typename
。出于某种原因,关于嵌套类型的template
的比特是众所周知的,但是typename
对嵌套模板的类似要求是相对未知的。
请注意,一般语法结构有点不同。 template
始终放在类型的全名前面,而A
插在中间。
同样,只有在访问依赖类型的模板成员时才需要这样做,在上面的示例中,printStuff
位于foo.getResult<>
。当您在main
中致电foo
时template
的类型不依赖,因此无需包含{{1}}关键字。
答案 1 :(得分:9)
根据C ++标准14.2 / 4,您的代码格式不正确:
成员模板专精的名称出现在后缀表达式中的
.
或->
之后,或 nested-name-specifier 在 qualified-id 中,postfix-expression或qualified-id显式依赖于template-parameter(14.6.2),成员模板名称必须以关键字{{1}为前缀}。否则,假定该名称命名非模板。
所以,你应该写template