2

Here on stackoverflow I've found several comments (see for example the comment by jrok on this question) stating that partial specializations of class member templates are allowed at non-namespace scope (in contrast to explicit specializations) like in the example below:

class A {
    template <class T, class U>
    class B {};
    template <class U>
    class B<void, U> {};
};

Also, this example compiles just fine with both gcc and clang. However in the c++03 standard text I can only find 14.5.4 [temp.class.spec] §6 (or 14.5.5 §5 in c++11) about this issue:

A class template partial specialization may be declared or redeclared in any namespace scope in which its definition may be defined (14.5.1 and 14.5.2).

Along with the following example:

template<class T> struct A {
    class C {
        template<class T2> struct B { };
    };
};

// partial specialization of A<T>::C::B<T2>
template<class T> template<class T2>
struct A<T>::C::B<T2*> { };

So, how about class template partial specializations at non-namespace scope? Are they allowed by the standard? And where can I find the relevant text?

Specifically, is my example valid (and would it still be valid if the enclosing class would be a template)? If not, are current compilers wrong to compile my example as stated above?

Community
  • 1
  • 1
Tom De Caluwé
  • 926
  • 5
  • 17

1 Answers1

0

This seems to be a bit confusing, as I agree the paragraph you quoted seems to disallow partial specializations inside class definitions. However, there's [temp.class.spec.mfunc]/2:

If a member template of a class template is partially specialized, the member template partial specializations are member templates of the enclosing class template; [...] [Example:

template<class T> struct A {
    template<class T2> struct B {}; // #1
    template<class T2> struct B<T2*> {}; // #2
};

template<> template<class T2> struct A<short>::B {}; // #3

A<char>::B<int*> abcip; // uses #2
A<short>::B<int*> absip; // uses #3
A<char>::B<int> abci; // uses #1

end example ]

IMHO this isn't very explicit; it doesn't allow partial specialization inside the class definition but rather (to me, seems to) specifies how member template specializations are treated.


Also see the Core Language Issue 708 and EWG Issue 41.

dyp
  • 38,334
  • 13
  • 112
  • 177
  • I find this answer very unsatisfactory :( but it's too long for a comment. – dyp Nov 08 '13 at 16:15
  • I had already noticed this as well. However, it doesn't actually answer the question, despite the example provided by the standard. I can add it to my question if you want. – Tom De Caluwé Nov 08 '13 at 16:20
  • About [Core Language Issue 708](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#708): it seems to me the correct behaviour is specified by the exact paragraph you quoted in your answer. Or am I missing something? – Tom De Caluwé Nov 08 '13 at 16:41