[temp.param] (original) (raw)

13 Templates [temp]

13.2 Template parameters [temp.param]

There is no semantic difference betweenclassandtypenamein atype-parameter-key.

typenamefollowed by anunqualified-idnames a template type parameter.

[ Example

:

class T { }; int i;

template<class T, T i> void f(T t) { T t1 = i;
::T t2 = ::i;
}

Here, the template f has a type-parametercalled T, rather than an unnamed non-typetemplate-parameter of class T.

end example

]

A storage class shall not be specified in atemplate-parameterdeclaration.

Types shall not be defined in a template-parameterdeclaration.

Atype-parameterwhose identifier does not follow an ellipsis defines itsidentifierto be atypedef-name(if declared withouttemplate) ortemplate-name(if declared withtemplate) in the scope of the template declaration.

[ Note

:

A template argument may be a class template or alias template.

For example,

template class myarray { };

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

end note

]

A type-constraint Q that designates a concept Ccan be used to constrain a contextually-determined type or template type parameter pack Twith a constraint-expression E defined as follows.

If Q is of the form C<A, ⋯, A>, then let E be C<T, A, ⋯, A>.

Otherwise, let E be C<T>.

If T is not a pack, then E is E, otherwise E is (E && ...).

The concept designated by a type-constraintshall be a type concept ([temp.concept]).

A type-parameter that starts with a type-constraintintroduces the immediately-declared constraint of the type-constraint for the parameter.

[ Example

:

template concept C1 = true; template<typename... Ts> concept C2 = true; template<typename T, typename U> concept C3 = true;

template struct s1;
template<C1... T> struct s2;
template<C2... T> struct s3;
template<C3 T> struct s4;
template<C3... T> struct s5;

end example

]

A non-type template-parametershall have one of the following (possibly cv-qualified) types:

The top-levelcv-qualifierson thetemplate-parameterare ignored when determining its type.

A structural type is one of the following:

An id-expression naming a non-type template-parameter of class type Tdenotes a static storage duration object of type const T, known as a template parameter object, whose value is that of the corresponding template argument after it has been converted to the type of the template-parameter.

All such template parameters in the program of the same type with the same value denote the same template parameter object.

A template parameter object shall have constant destruction ([expr.const]).

[ Note

:

If an id-expression names a non-type non-reference template-parameter, then it is a prvalue if it has non-class type.

Otherwise, if it is of class type T, it is an lvalue and has type const T ([expr.prim.id.unqual]).

end note

]

[ Example

:

using X = int; struct A {}; template<const X& x, int i, A a> void f() { i++;

&x;
&i;
&a;
int& ri = i;
const int& cri = i;
const A& ra = a;
}

end example

]

[ Note

:

A non-typetemplate-parametercannot be declared to have type cv void.

[ Example

:

template class X;
template<void* pv> class Y;

end example

]

end note

]

A non-typetemplate-parameter of type “array of T” orof function type Tis adjusted to be of type “pointer to T”.

[ Example

:

template<int* a> struct R { }; template<int b[5]> struct S { }; int p; R<&p> w;
S<&p> x;
int v[5]; R y;
S z;

end example

]

A non-type template parameter declared with a type that contains a placeholder type with a type-constraintintroduces the immediately-declared constraint of the type-constraintfor the invented type corresponding to the placeholder ([dcl.fct]).

A defaulttemplate-argumentmay be specified in a template declaration.

A defaulttemplate-argumentshall not be specified in thetemplate-parameter-listsof the definition of a member of a class template that appears outside of the member's class.

A defaulttemplate-argumentshall not be specified in a friend class template declaration.

If a friend function template declaration specifies a defaulttemplate-argument, that declaration shall be a definition and shall be the only declaration of the function template in the translation unit.

The set of defaulttemplate-argumentsavailable for use is obtained by merging the default arguments from all prior declarations of the template in the same way default function arguments are ([dcl.fct.default]).

[ Example

:

template<class T1, class T2 = int> class A; template class A;

is equivalent to

template class A;

end example

]

If atemplate-parameterof a class template, variable template, or alias template has a defaulttemplate-argument, each subsequenttemplate-parametershall either have a defaulttemplate-argumentsupplied or be a template parameter pack.

If a template-parameterof a primary class template, primary variable template, or alias template is a template parameter pack, it shall be the lasttemplate-parameter.

A template parameter pack of a function template shall not be followed by another template parameter unless that template parameter can be deduced from the parameter-type-list ([dcl.fct]) of the function template or has a default argument ([temp.deduct]).

A template parameter of a deduction guide template ([temp.deduct.guide]) that does not have a default argument shall be deducible from the parameter-type-list of the deduction guide template.

[ Example

:

template class B;

template<class... T, class... U> void f() { }
template<class... T, class U> void g() { }

end example

]

Atemplate-parametershall not be given default arguments by two different declarations in the same scope.

[ Example

:

template class X; template class X { };

end example

]

When parsing a defaulttemplate-argumentfor a non-typetemplate-parameter, the first non-nested>is taken as the end of thetemplate-parameter-listrather than a greater-than operator.

[ Example

:

template 4 >
class X { };

template 4) >
class Y { };

end example

]

When such default arguments are specified, they apply to the templatetemplate-parameterin the scope of the templatetemplate-parameter.

[ Example

:

template <template class T> struct A { inline void f(); inline void g(); }; template <template class T> void A::f() { T<> t;
} template <template class T> void A::g() { T<> t;
}

end example

]

A template parameter pack that is a parameter-declaration whose type contains one or more unexpanded packs is a pack expansion.

Similarly, a template parameter pack that is a type-parameter with atemplate-parameter-list containing one or more unexpanded packs is a pack expansion.

A type parameter pack with a type-constraint that contains an unexpanded parameter pack is a pack expansion.

A template parameter pack that is a pack expansion shall not expand a template parameter pack declared in the sametemplate-parameter-list.

[ Example

:

template <class... Types>
class Tuple;

template <class T, int... Dims>
struct multi_array;

template <class... T> struct value_holder { template <T... Values> struct apply { };
};

template <class... T, T... Values>
struct static_array;

end example

]