哪个编译器是正确的? “模板”在需要模板化返回类型之前?
此片段(取自这个问题)用 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;
}
This snippet (taken from this question) compiles fine with g++ (as seen), so long the template
before the return type is there. In contrast, VC10 does not compile that code with the following error:
error C2244: 'A::getAttr' : unable to match function definition to an existing declaration
If I remove the template
, VC10 is happy but g++ screams this error:
error: non-template 'AttributeType' used as template
note: use 'A::template AttributeType' to indicate that it is a template
Is it again because of VC's broken two-phase look-up or what is the cause? Which compiler is right here? I suspect g++ to be correct, as I have a vague memory of template
being needed here, like with the rebind
template inside of allocators.
Edit: We have a winner: g++/GCC (surprise surprise...).
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
海湾合作委员会是对的。
AttributeType
是一个依赖的模板名称,后面是尖括号<
,因此这里需要关键字template
来消除歧义1,让编译器清楚后面的是模板名称。 §14.2/4 中提到了该规则:1 @Johannes 在这里写了一个非常好的解释:
我必须在哪里以及为什么必须放置“template”和“typename”关键字?
GCC is right.
AttributeType
is a dependent template-name which is followed by angle bracket<
, so the keywordtemplate
is required here to remove the ambiguity1, making it clear to the compiler that what is followed is a template-name. The rule is mentioned in §14.2/4:1 @Johannes has written a very good explanation here:
Where and why do I have to put the "template" and "typename" keywords?