Files
2025-10-25 03:02:53 +03:00

12 KiB
Raw Permalink Blame History

[temp.class]

13 Templates [temp]

13.7 Template declarations [temp.decls]

13.7.2 Class templates [temp.class]

13.7.2.1 General [temp.class.general]

1

#

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

2

#

[Example 1:

It is possible for a single class templateList to provide an unbounded set of class definitions: one class List for every type T, each describing a linked list of elements of type T.

Similarly, a class template Array describing a contiguous, dynamic array can be defined like this:template class Array { T* v; int sz;public:explicit Array(int); T& operator; T& elem(int i) { return v[i]; }};

The prefix template specifies that a template is being declared and that atype-name T can be used in the declaration.

In other words,Array is a parameterized type withT as its parameter.

— end example]

3

#

[Note 1:

When a member of a class template is defined outside of the class template definition, the member definition is defined as a template definition with thetemplate-head equivalent to that of the class template.

The names of the template parameters used in the definition of the member can differ from the template parameter names used in the class template definition.

The class template name in the member definition is followed by the template argument list of the template-head ([temp.arg]).

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

template<class T2, class T1> void A<T2,T1>::f1() { } // OKtemplate<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() { } // OKtemplate<class ... Types> void B::f4() { } // error

template concept C = true;template concept D = true;

template struct S {void f(); void g(); void h(); template struct Inner;};

template void S::f() { } // OK, template-heads matchtemplate void S::g() { } // error: no matching declaration for Stemplate requires C // ill-formed, no diagnostic required: template-heads arevoid S::h() { } // functionally equivalent but not equivalenttemplate templatestruct S::Inner { }; // OK — end example]

— end note]

4

#

In a 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]).

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

1

#

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 Array { T* v; int sz;public:explicit Array(int); T& operator; T& elem(int i) { return v[i]; }};

declares three member functions of a class template.

The subscript function can be defined like this:template T& Array::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 concept C = requires {typename T::type;};

template struct S {void f() requires C; void g() requires C;};

templatevoid S::f() requires C { } // OKtemplatevoid S::g() { } // error: no matching function in S

— end example]

2

#

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

[Example 2:

Thetemplate-argument forArray::operator[] will be determined by theArray to which the subscripting operation is applied.

Array v1(20); Array v2(30);

v1[3] = 7; // Array::operator[] v2[3] = dcomplex(7,8); // Array::operator[] — end example]

13.7.2.3 Deduction guides [temp.deduct.guide]

1

#

Deduction guides are used when a template-name or splice-type-specifier appears as a type specifier for a deduced class type ([dcl.type.class.deduct]).

Deduction guides are not found by name lookup.

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

deduction-guide:
explicit-specifieropt template-name ( parameter-declaration-clause ) -> simple-template-id requires-clauseopt ;

2

#

[Example 1: template<class T, class D = int>struct S { T data;};template S(U) -> S;

struct A {using type = short; operator type();}; S x{A()}; // x is of type S<short, int> — end example]

3

#

The same restrictions apply to the parameter-declaration-clause of a deduction guide as in a function declaration ([dcl.fct]), except that a generic parameter type placeholder ([dcl.spec.auto]) shall not appear in the parameter-declaration-clause of a deduction guide.

The simple-template-id shall name a class template specialization.

The template-name shall be the same identifier as the template-name of the simple-template-id.

A deduction-guide shall inhabit the scope to which the corresponding class template belongs and, for a member class template, have the same access.

Two deduction guide declarations for the same class template shall not have equivalent parameter-declaration-clauses if either is reachable from the other.

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

1

#

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 struct A {class B;}; A::B* b1; // OK, requires A to be defined but not A::Btemplate class A::B { }; A::B b2; // OK, requires A::B to be defined

— end note]

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

1

#

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 X {static T s;};template T X::s = 0;

struct limits {templatestatic const T min; // declaration};

templateconst T limits::min = { }; // definition — end example]

2

#

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 struct A {static int i[];};template int A::i[4]; // 4 elementstemplate <> int A::i[] = { 1 }; // OK, 1 element — end example]

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

1

#

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

[Example 1: template struct A {enum E : T;};template enum A::E : T { e1, e2 }; A::E e = A::e1; — end example]