This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 110b. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2023-01-15


531. Defining members of explicit specializations

Section: 13.9.4  [temp.expl.spec]     Status: C++11     Submitter: Mike Miller     Date: 1 October 2005

[Voted into the WP at the March, 2011 meeting as part of paper N3262.]

The Standard does not fully describe the syntax to be used when a member of an explicitly-specialized member class or member class template is defined in namespace scope. 13.9.4 [temp.expl.spec] paragraph 4 says that the “explicit specialization syntax” (presumably referring to “template<>”) is not used in defining a member of an explicit specialization when a class template is explicitly specialized as a class. However, nothing is said anywhere about how to define a member of a specialization when:

  1. the entity being specialized is a class (member of a template class) rather than a class template.

  2. the result of the specialization is a class template rather than a class (cf 13.9.4 [temp.expl.spec] paragraph 18, which describes this case as a “member template that... remain[s] unspecialized”).

(See paper J16/05-0148 = WG21 N1888 for further details, including a survey of existing implementation practice.)

Notes from the October, 2005 meeting:

The CWG felt that the best approach, balancing consistency with implementation issues and existing practice, would be to require that template<> be used when defining members of all explicit specializations, including those currently covered by 13.9.4 [temp.expl.spec] paragraph 4.

Proposed resolution (February, 2010) [SUPERSEDED]:

Change 13.9.4 [temp.expl.spec] paragraph 5 as follows:

...The definition of an explicitly specialized class is unrelated to the definition of a generated specialization. That is, its members need not have the same names, types, etc. as the members of a generated specialization. Definitions of members of an explicitly specialized class are defined in the same manner as members of normal classes, and not using the syntax for explicit specialization using the same template<> prefix(es) as the explicitly specialized class. [Example:

    template<class T> struct A {
      void f(T) { /* ... */ }
      struct B { /* ... */ };
      template<class U> struct C { /* ... */ };
    };
    template<> struct A<int> {
      void f(int);
      struct B;
      template<class U> struct C;
    };
    void h() {
      A<int> a;
      a.f(16); // A<int>::f must be defined somewhere
    }
    // explicit specialization syntax not used for a member of
    // explicitly specialized class template specialization
    // members of explicitly specialized classes are defined using
    //the same syntax as the explicitly specialized class:
    template<> void A<int>::f(int) { /* ... */ }
    template<> struct A<int>::B { /* ... */ };
    template<> template<class T> struct A<int>::C { /* ... */ };

end example]

Note (June, 2010):

Because the survey of implementations on which the CWG relied in reaching this resolution is quite old, a new survey of current practice is needed.