c++ - 哪个编译器是对的?需要模板化返回类型之前的 'template'?

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

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/

相关文章:

c++ - 在 C/C++ 中编写 "pointer to something"的好方法

c++ - 将类型特征与可变参数模板参数一起使用

c++ - 如何为 operator<< 创建 C++ 模板

c++ - 将 Unicode 转换为多字节

c# - Windows API 和 .net 语言

c++ - 在 Debug模式下找不到 msvcr90d.dll

c++ - ARM 上的 std::atomic<bool> 无锁不一致(树莓派 3)

c++ - String 类的隐式构造函数

c++ - '仅将成员函数添加到类的专用模板

c++ - 传递参数为 `const` 的奇怪效果