Xeo*_*Xeo 15 c++ templates correctness g++ visual-c++
这段代码(取自这个问题)用g ++(如图所示)编译得很好,所以template返回类型就在那之前.相反,VC10不会使用以下错误编译该代码:
错误C2244:'A :: getAttr':无法将函数定义与现有声明匹配
如果我删除了template,VC10很高兴,但g ++尖叫这个错误:
错误:非模板'AttributeType'用作模板
注意:使用'A :: template AttributeType'表示它是模板
是否因为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;
}
Run Code Online (Sandbox Code Playgroud)
Naw*_*waz 10
GCC是对的.AttributeType是一个依赖的模板名称,后跟尖括号<,因此template这里需要关键字来消除歧义1,使编译器清楚地知道所遵循的是模板名称.该规则在§14.2/ 4中提到:
当成员模板专业化的名称出现之后.或 - >在postfix-expression中,或在qualified-id中的nested-name-specifier之后,postfix-expression或qualified-id显式依赖于template-parameter(14.6.2),成员模板名称必须是以关键字模板为前缀.否则,假定该名称命名非模板.
1 @Johannes在这里写了一个非常好的解释:
我必须在何处以及为何要使用"模板"和"typename"关键字?