Clang(OS X)在特定的嵌套声明中需要"template"关键字,而VS禁止它

Dan*_*aum 7 c++ templates clang c++11 visual-studio-2012

我正在两个编译器(Clang on Xcode v5.0.2和Visual Studio 2012 Update 4)中编写一个跨平台的应用程序,我遇到了两个编译器不同意template关键字使用所需语法的场景.嵌套声明.

这是代码(归结为一个易于重现的测试用例):

template<typename T>
struct Base
{
    template<typename U>
    struct InnerBase
    {};
};

template<typename T, typename U>
struct Derived : public Base<T>
{
    // the "template" keyword is REQUIRED in Clang/OSX
    struct InnerDerived : public Base<T>::template InnerBase<U>
    {};

    // the "template" keyword is FORBIDDEN in Visual Studio 2012
    struct InnerDerived : public Base<T>::InnerBase<U>
    {};
};

int main()
{
    Derived<int, int>::InnerDerived foo;
}
Run Code Online (Sandbox Code Playgroud)

如上所述,两个编译器不同意使用"template"关键字.

对于Clang,如果包含template关键字,则错误为:

使用'template'关键字将'InnerBase'视为依赖模板名称

对于Visual Studio,当template关键字包括,错误的是:

'Base :: InnerBase':使用类模板需要模板参数列表

我已经查看了关于template关键字使用规则的各种其他StackOverflow问题(例如,我在哪里以及为什么要放置"模板"和"typename"关键字?).但是,看看这个和其他类似的问题,并没有让我有信心声称一个编译器正确地实现了C++ 11而另一个编译器没有.

(请注意,铛的错误对我来说很有意义,而VS错误没有多大意义的,我是因为我似乎感到,包括模板参数列表.)

在这种情况下哪个编译器是正确的?是否应该在template上面的示例代码中包含关键字(符合C++ 11)?

(可能我没有正确设置编译器设置以在一种或另一种情况下使用C++ 11 - 在这种情况下,我的问题仍然存在:上面代码的哪个版本是正确的C++ 11代码?)

Die*_*ühl 7

似乎相关条款是14.2(temp.names)第4段:

当成员模板特化的名称出现在postfix-expression 之后.或之后,或者出现在->qualified-id中的嵌套名称说明符之后,并且postfix-expression的对象表达式是类型相关的或嵌套名称说明符在qualified-id中引用依赖类型,但名称不是当前实例化的成员(14.6.2.1),成员模板名称必须以关键字为前缀template.

我认为这template是必需的.跟进DyP的评论,即使不是必需的,拒绝关键字似乎也是错误的(同一条款的第5段):

以关键字为前缀的名称template应为template-id,或者名称应引用类模板.[注意:关键字template可能不适用于类模板的非模板成员.-end note] [注意:与typename前缀的情况一样,在template不是绝对必要的情况下允许使用前缀; 即,当嵌套名称说明符或在左侧的表达->.上的模板参数不依赖,或者利用没有出现在一个template.端说明的范围.


Cas*_*sey 5

Clang是正确的,Base<T>取决于模板参数.这是Visual C++没有实现模板的两阶段名称查找的另一个症状.