【问题标题】:Which compiler is right? 'template' before templated return type needed?哪个编译器是对的?需要模板化返回类型之前的“模板”?
【发布时间】:2011-09-08 02:31:47
【问题描述】:

This snippet(取自this question)可以用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;
}

【问题讨论】:

  • 发布问题中的代码。堆栈溢出支持并强烈鼓励这样做。
  • 一般来说,用于标准合规性的非正式“参考编译器”是 Comeau,您可以尝试提交您的 sn-p here 以查看其判断。 - 编辑:现在试过了,sn-p 编译得很好,就像在 Ideone 上一样。
  • clang++ 2.9 和 Intel C/C++ 11.1 端也带有 gcc。
  • 等等,你是在问 MSVC 或 gcc 是否能正确使用 templatetypename 关键字? MSVC 10?严重地? MS 对templates 的实现在当前版本中仍然非常糟糕,更不用说那么旧的了。
  • @Yakk 你确实意识到这个问题已经超过 3 年了?

标签: c++ templates visual-c++ g++ correctness


【解决方案1】:

GCC 是对的。 AttributeType 是一个依赖模板名,后跟尖括号&lt;,所以这里需要关键字template 来消除歧义1,让编译器清楚什么是后面是模板名称。 §14.2/4 中提到了该规则:

当成员模板的名称 专业化出现在 之后。或-> 在后缀表达式中或之后 嵌套名称说明符 合格的 id 和 后缀表达式或限定 ID 显式地依赖于 模板参数(14.6.2), 成员模板名称必须加前缀 通过关键字模板。否则 假定名称为 a 非模板。

1 @Johannes 在这里写了一个很好的解释:

Where and why do I have to put the "template" and "typename" keywords?

【讨论】:

  • 谢谢,这是我正在寻找的标准报价。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 2019-06-09
  • 1970-01-01
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多