Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested class explicit specilization: different compiler behavior

The following code 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++ compilation error message:

error C2906: 'void A<int>::B<char>::foo(void)': explicit specialization requires 'template <>'

What behavior is standard compliant in this case?

like image 997
Constructor Avatar asked Apr 23 '18 15:04

Constructor


1 Answers

VC++ is wrong. Potentially misapprehending the following clause:

Members of an explicitly specialized class template are defined in the same manner as members of normal classes, and not using the template<> syntax. The same is true when defining a member of an explicitly specialized member class (*). However, template<> is used in defining a member of an explicitly specialized member class template that is specialized as a class template.

The intent of the latter rule is to disambiguate:

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

However, in your case, the (*) case applies.

like image 73
Columbo Avatar answered Oct 17 '22 16:10

Columbo