首页 文章

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

提问于
浏览
7

我正在两个编译器(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;
}

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

对于Clang,当包含 template 关键字 not 时,错误为:

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

对于Visual Studio,当包含 template 关键字 is 时,错误为:

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

我查看了有关 template 关键字使用规则的各种其他StackOverflow问题(例如,Where and why do I have to put the "template" and "typename" keywords?) . 但是,看看这个和其他类似的问题,并没有让我有信心声称一个编译器正确地实现了C 11而另一个编译器没有 .

(请注意,Clang 's error makes sense to me, while the VS error doesn' t对我来说很有意义,因为我似乎包含了模板参数列表 . )

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

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

2 回答

  • 7

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

    之后出现成员模板专业化的名称 . 或者 - >在postfix-expression中或者在qualified-id中的nested-name-specifier之后,postfix-expression的对象表达式依赖于类型,或者qualified-id中的nested-name-specifier指的是依赖类型,但名称不是当前实例化的成员(14.6.2.1),成员模板名称必须以关键字模板为前缀 .

    我认为这需要 template . 跟进DyP 's comment, it seems certainly wrong to reject the keyword even if it isn' t(同一条款第5段):

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

  • 5

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

相关问题