This snippet (取自 this question )使用 g++ 编译得很好(如图所示),只要 template
在返回类型之前存在。相比之下,VC10 不编译该代码并出现以下错误:
error C2244: 'A::getAttr' : unable to match function definition to an existing declaration
如果我删除 template
,VC10 很高兴,但 g++ 会报错:
error: non-template 'AttributeType' used as template
note: use 'A::template AttributeType' to indicate that it is a template
又是VC破了两相查找还是什么原因?哪个编译器在这里?我怀疑 g++ 是正确的,因为我对这里需要的 template
有模糊的内存,就像分配器中的 rebind
模板一样。
编辑:我们有一个赢家:g++/GCC(惊喜...)。
template <typename T, typename K>
class A {
public:
T t;
K k;
template <int i, int unused = 0>
struct AttributeType{
};
template <int i>
AttributeType<i> getAttr();
};
template <typename T, typename K>
template <int i>
typename A<T, K>::template AttributeType<i> A<T, K>::getAttr() {
// ^^^^^^^^ -- needed or not?
return t;
}
int main(){
A<int,int> a;
}
最佳答案
GCC 是对的。 AttributeType
是一个从属模板名称,后跟尖括号 <
, 所以关键字 template
此处需要消除歧义1,使编译器清楚地知道后面是模板名称。 §14.2/4 中提到了该规则:
When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.
1 @Johannes 在这里写了一个很好的解释:
Where and why do I have to put the "template" and "typename" keywords?
关于c++ - 哪个编译器是对的?需要模板化返回类型之前的 'template'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6232294/