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

标签 c++ templates visual-studio-2012 c++11 clang

我正在使用两个编译器(Xcode v5.0.2 上的 Clang 和 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关键字时,错误是:

Use 'template' keyword to treat 'InnerBase' as a dependent template name

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

'Base::InnerBase' : use of class template requires template argument list

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

(请注意,Clang 的错误对我来说很有意义,而 VS 错误对我来说没有多大意义,因为看起来我包括了模板参数列表。)

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

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

最佳答案

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

When the name of a member template specialization appears after . or ->in a postfix-expression or after a nested-name-specifier in a qualified-id, and the object expression of the postfix-expression is type-dependent or the nested-name-specifier in the qualified-id refers to a dependent type, but the name is not a member of the current instantiation (14.6.2.1), the member template name must be prefixed by the keyword template.

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

A name prefixed by the keyword template shall be a template-id or the name shall refer to a class template. [Note: The keyword template may not be applied to non-template members of class templates. —end note] [Note: As is the case with the typename prefix, the template prefix is allowed in cases where it is not strictly necessary; i.e., when the nested-name-specifier or the expression on the left of the -> or . is not dependent on a template-parameter, or the use does not appear in the scope of a template.—end note].

关于c++ - Clang (OS X) 在特定的嵌套声明中需要 "template"关键字,而 VS 禁止它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20847637/

相关文章:

c++ - 在带有 VS 2008 的 Qt 4.8.5 网络示例中找不到 ui_chatdialog.h

c++ - 返回 char* 形式的 C++ 函数

c++ - C++ OPENCV 4.3.0 x64为什么face_cascade抛出错误?

django 模板编码样式换行用于长代码行

c++ - 在模板上下文中通过引用传递的参数的 'const' 限定符的位置

c# - Microsoft Fakes x64 而不是 x86 和 v4.5

qt - fatal error LNK1104 : cannot open file 'mfc110d.lib'

c++ - 抽象类c++的对象作为函数的参数

c++ - 使用 TRewindReaderProc 倒回 TJSONIterator 类的输入数据

c++ - 存储指向 std::max 的函数指针的自动变量