嵌套类显式规范:不同的编译器行为

时间:2018-04-23 15:38:31

标签: c++ templates language-lawyer template-specialization explicit-specialization

以下代码compiles fine with clang++ 6.0.0 and g++ 7.3.0 (compilation flags are -std=c++14 -Wall -Wextra -Werror -pedantic-errors) but fails to compile with vc++ 19.10.25017 (compilation flag is /Za)

template <typename>
struct A
{
    template <typename>
    struct B
    {
    };
};

template <>
template <>
struct A<int>::B<char>
{
    static void foo();
};

void A<int>::B<char>::foo()
{
}

int main()
{
}

vc ++ 编译错误消息:

  

错误C2906:'void A&lt; int&gt; :: B&lt; char&gt; :: foo(void)':显式特化需要'template&lt;&gt;'

在这种情况下,符合标准的行为是什么?

1 个答案:

答案 0 :(得分:4)

VC ++错了。可能会误解following clause

  

明确专门的类模板的成员在。中定义   与普通类的成员相同,而不是使用template<>   句法。定义明确的成员时也是如此   专门的成员类(*)。但是,template<>用于定义专门用作类模板的显式专用成员类模板的成员。

后一条规则的目的是消除歧义:

// Which template does this header appertain to?
template<class U> void A<short>::C<U>::f() { /* ... */ } 

但是,在您的情况下,(*)情况适用。