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

2024-03-20


1874. Type vs non-type template parameters with class keyword

Section: 13.2  [temp.param]     Status: CD4     Submitter: Richard Smith     Date: 2014-02-18

[Moved to DR at the November, 2014 meeting.]

The Standard is not clear enough that a template parameter like class T is to be interpreted as a type parameter and not an ill-formed non-type parameter of class type T.

Proposed resolution (October, 2014):

  1. Change 13.2 [temp.param] paragraph 2 as follows, moving the example from paragraph 3 to paragraph 2:

  2. There is no semantic difference between class and typename in a template-parameter. typename followed by an unqualified-id names a template type parameter. typename followed by a qualified-id denotes the type in a non-type137 parameter-declaration. A template-parameter of the form class identifier is a type-parameter. [Example:

      class T { /* ... */ };
      int i;
    
      template<class T, T i> void f(T t) {
        T t1 = i;      // template-parameters T and i
        ::T t2 = ::i;  // global namespace members T and i
      }
    

    Here, the template f has a type-parameter called T, rather than an unnamed non-type template-parameter of class T. —end example]. A storage class shall not be specified in a template-parameter declaration. Types shall not be defined in a template-parameter declaration. [Note: A template parameter may be a class template. For example... —end note]

  3. Change 13.2 [temp.param] paragraph 3 as follows, moving the example from paragraph 2 to paragraph 3:

  4. A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name (if declared with class or typename) or template-name (if declared with template) in the scope of the template declaration. [Note: Because of the name lookup rules, a template-parameter that could be interpreted as either a non-type template-parameter or a type-parameter (because its identifier is the name of an already existing class) is taken as a type-parameter. For example... —end note] [Note: A template parameter may be a class template. For example,

      template<class T> class myarray { /* ... */ };
    
      template<class K, class V, template<class T> class C = myarray>
      class Map {
        C<K> key;
        C<V> value;
      };
    

    end note]