As a general rule, explicit specialization is allowed on a namespace scope. The following code:
template<typename T>
class B {
template<typename U> void test(T) {};
template<> void test(int) {};
};
make g++ produce the following error:
error: explicit specialization in non-namespace scope
At the same time, friend function template specialization is one of two possible ways to make friend function templates work inside class templates. The following code works like a charm:
template<typename T>
class B;
template<typename T>
void test(B<T>);
template<typename T>
class B {
friend void test<>(B<T>);
};
At the same time, the following does not compile, giving the same error as for the Snippet one:
template<typename T>
class B {
template<typename U> friend void test(U);
template<>friend void test<B<T>>(B<T>);
};
My questions are:
friend void test<>(B<T>);
EDIT 1 Fixed syntax errors in snippet 1.
Assuming you fix the obvious syntax errors in your example:
Explicit specializations of member function templates are also allowed in class scope. This has been clarified a long time ago, but it is a defect report that GCC has never implemented (so far), see GCC bug report.
However, a friend
declaration may not declare an explicit or partial specialization. Doing that isn't really sensible, because the function (template) declared by the friend
declaration belongs to the enclosing namespace scope, not the class scope.
As you showed, it is already possible to friend a specific specialization of a function template. It doesn't matter to the friend
declaration whether or not the specialization is declared as an explicit specialization, so there is no reason to allow it. You can declare the explicit specialization of the function template later at namespace scope, where it usually belongs for a non-member function template.
And while
friend void test<>(B<T>);
declares a specific specialization of the function template test
to be a friend of the class, it isn't an explicit specialization declaration and doesn't declare that specialization of the function to be explicitly-specialized. The declaration only makes the function specialization a friend
, but the primary template will still be used to implicitly instantiate a definition for that specialization.
On the other hand an explicit specialization declaration declares that no implicit instantiation from the primary template should be used for that function template specialization, but that instead the corresponding explicit specialization definition for that function template specialization should be used.
An explicit specialization can be clearly identified by its template head being exactly template<>
, no other declaration is an explicit specialization and no explicit specialization looks different.