14 Templates [temp]

14.5 Template declarations [temp.decls]

14.5.1 Class templates [temp.class]

A class template defines the layout and operations for an unbounded set of related types. [ Example: a single class template List might provide a common definition for list of int, list of float, and list of pointers to Shapes.  — end example ]

Example: An array class template might be declared like this:

template<class T> class Array {
  T* v;
  int sz;
public:
  explicit Array(int);
  T& operator[](int);
  T& elem(int i) { return v[i]; }
};

The prefix template <class T> specifies that a template is being declared and that a type-name T will be used in the declaration. In other words, Array is a parameterized type with T as its parameter.  — end example ]

When a member function, a member class, a member enumeration, a static data member or a member template of a class template is defined outside of the class template definition, the member definition is defined as a template definition in which the template-parameters are those of the class template. The names of the template parameters used in the definition of the member may be different from the template parameter names used in the class template definition. The template argument list following the class template name in the member definition shall name the parameters in the same order as the one used in the template parameter list of the member. Each template parameter pack shall be expanded with an ellipsis in the template argument list. [ Example:

template<class T1, class T2> struct A {
  void f1();
  void f2();
};

template<class T2, class T1> void A<T2,T1>::f1() { }    // OK
template<class T2, class T1> void A<T1,T2>::f2() { }    // error
template<class ... Types> struct B {
  void f3();
  void f4();
};

template<class ... Types> void B<Types ...>::f3() { }    // OK
template<class ... Types> void B<Types>::f4() { }        // error

 — end example ]

In a redeclaration, partial specialization, explicit specialization or explicit instantiation of a class template, the class-key shall agree in kind with the original class template declaration ([dcl.type.elab]).

14.5.1.1 Member functions of class templates [temp.mem.func]

A member function of a class template may be defined outside of the class template definition in which it is declared. [ Example:

template<class T> class Array {
  T* v;
  int sz;
public:
  explicit Array(int);
  T& operator[](int);
  T& elem(int i) { return v[i]; }
};

declares three function templates. The subscript function might be defined like this:

template<class T> T& Array<T>::operator[](int i) {
  if (i<0 || sz<=i) error("Array: range error");
  return v[i];
}

 — end example ]

The template-arguments for a member function of a class template are determined by the template-arguments of the type of the object for which the member function is called. [ Example: the template-argument for Array<T> :: operator [] () will be determined by the Array to which the subscripting operation is applied.

Array<int> v1(20);
Array<dcomplex> v2(30);

v1[3] = 7;                      // Array<int>::operator[]()
v2[3] = dcomplex(7,8);          // Array<dcomplex>::operator[]()

 — end example ]

14.5.1.2 Member classes of class templates [temp.mem.class]

A class member of a class template may be defined outside the class template definition in which it is declared. [ Note: The class member must be defined before its first use that requires an instantiation ([temp.inst]). For example,

template<class T> struct A {
  class B;
};
A<int>::B* b1;                  // OK: requires A to be defined but not A::B
template<class T> class A<T>::B { };
A<int>::B  b2;                  // OK: requires A::B to be defined

 — end note ]

14.5.1.3 Static data members of class templates [temp.static]

A definition for a static data member may be provided in a namespace scope enclosing the definition of the static member's class template. [ Example:

template<class T> class X {
  static T s;
};
template<class T> T X<T>::s = 0;

 — end example ]

An explicit specialization of a static data member declared as an array of unknown bound can have a different bound from its definition, if any. [ Example:

template <class T> struct A {
  static int i[];
};
template <class T> int A<T>::i[4];    // 4 elements
template <> int A<int>::i[] = { 1 };  // OK: 1 element

 — end example ]

14.5.1.4 Enumeration members of class templates [temp.mem.enum]

An enumeration member of a class template may be defined outside the class template definition. [ Example:

template<class T> struct A {
  enum E : T;
};
A<int> a;
template<class T> enum A<T>::E : T { e1, e2 };
A<int>::E e = A<int>::e1;

 — end example ]