[temp.class] (original) (raw)

13 Templates [temp]

13.7 Template declarations [temp.decls]

13.7.2 Class templates [temp.class]

13.7.2.1 General [temp.class.general]

Aclass templatedefines the layout and operations for an unbounded set of related types.

[Example 1:

A single class templateListmight provide an unbounded set of class definitions: one class List<T> for every type T, each describing a linked list of elements of type T.

Similarly, a class template Array describing a contiguous, dynamic array might be defined 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 atype-name Tmay be used in the declaration.

In other words,Arrayis a parameterized type withTas 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 thetemplate-head is equivalent to that of the class template ([temp.over.link]).

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 2: template<class T1, class T2> struct A { void f1();void f2();};template<class T2, class T1> void A<T2,T1>::f1() { } template<class T2, class T1> void A<T1,T2>::f2() { }

template<class ... Types> struct B { void f3();void f4();};template<class ... Types> void B<Types ...>::f3() { } template<class ... Types> void B<Types>::f4() { }

template<typename T> concept C = true;template<typename T> concept D = true;template<C T> struct S { void f();void g();void h();template<D U> struct Inner;};template<C A> void S<A>::f() { } template<typename T> void S<T>::g() { } template<typename T> requires C<T> void S<T>::h() { } template<C X> template<D Y> struct S<X>::Inner { }; — _end example_]

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

13.7.2.2 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 1: 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 member functions of a class template.

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];}

A constrained member function can be defined out of line:template<typename T> concept C = requires { typename T::type;};template<typename T> struct S { void f() requires C<T>;void g() requires C<T>;};template<typename T> void S<T>::f() requires C<T> { } template<typename T> void S<T>::g() { }

— _end example_]

Thetemplate-argument_s_for a member function of a class template are determined by thetemplate-argument_s_of the type of the object for which the member function is called.

[Example 2:

Thetemplate-argumentforArray<T>​::​operator[]will be determined by theArrayto which the subscripting operation is applied.

Array<int> v1(20); Array<dcomplex> v2(30); v1[3] = 7; v2[3] = dcomplex(7,8); — _end example_]

13.7.2.3 Deduction guides [temp.deduct.guide]

Deduction guides are not found by name lookup.

Instead, when performing class template argument deduction ([over.match.class.deduct]), any deduction guides declared for the class template are considered.

[Example 1: template<class T, class D = int> struct S { T data;};template<class U>S(U) -> S<typename U::type>;struct A { using type = short;operator type();}; S x{A()}; — _end example_]

A deduction-guideshall be declared in the same scope as the corresponding class template and, for a member class template, with the same access.

Two deduction guide declarations in the same translation unit for the same class template shall not have equivalent parameter-declaration-clauses.

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

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

[Note 1:

The member class 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; template<class T> class A<T>::B { }; A<int>::B b2;

— _end note_]

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

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

[Example 1: template<class T> class X { static T s;};template<class T> T X<T>::s = 0;struct limits { template<class T> static const T min; };template<class T> const T limits::min = { }; — _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 2: template <class T> struct A { static int i[];};template <class T> int A<T>::i[4]; template <> int A<int>::i[] = { 1 }; — _end example_]

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

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

[Example 1: 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_]