哪个编译器是正确的? 'template'在需要模板化返回类型之前?
Which compiler is right? 'template' before templated return type needed?
这个片段(取自这个问题)用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;
}
GCC是对的。AttributeType
是一个从属模板名称,后面跟有尖括号<
,因此这里需要关键字template
来消除歧义1,使编译器清楚地知道后面是一个模板名称。§14.2/4:中提到了该规则
当成员模板的名称专业化出现在之后。或->在后缀表达式中,或在中的嵌套名称说明符合格的id,以及后缀表达式或限定id显式依赖于模板参数(14.6.2)成员模板名称必须加前缀通过关键字模板。否则name被假定为非模板。
1@Johannes在这里写了一个非常好的解释:
我必须把";模板";以及";typename";关键词?
相关文章:
- 在模板化成员函数的返回类型中使用 std::enable_if 时的编译器差异
- 使用typedef'ed返回类型声明友元函数时出现编译器错误
- 为什么编译器不能从返回类型中推断出模板参数?
- 编译器无法推断返回类型?
- 如何允许编译器推断出正确的返回类型以进行模板get函数
- 为什么编译器无法推断返回类型?
- GCC 中的编译器错误,但在将 decltype 与具有尾随返回类型语法的模板化成员函数一起使用时没有 clang
- typedef映射作为返回类型到函数会引发编译器错误
- 为什么编译器需要在已经类限定的成员函数定义的返回类型上使用类限定符
- 当我使用模板时,编译器无法将函数的返回类型从 double 转换为 int
- 函数声明和定义的返回类型不匹配,编译器可以吗?
- 编译器的函数返回类型验证
- C++ typedef 和返回类型:如何让编译器识别使用 typedef 创建的返回类型
- g++编译器忽略const返回类型
- 模板类中的尾随返回类型(GNU和Microsoft编译器之间的矛盾)
- 如何让编译器推断模板的返回类型
- 编译器警告:无法推导lambda返回类型
- 函数映射容器中C++函数返回类型重载:自动推导失败,并出现编译器错误
- 为什么编译器不显示这些返回类型的错误?
- 如何让编译器推断出c++ 11中模板化方法的返回类型