[temp.param] (original) (raw)

13 Templates [temp]

13.2 Template parameters [temp.param]

The syntax fortemplate-parameter_s_is:

type-parameter-key:
class
typename

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

typenamefollowed by anunqualified-idnames a template type parameter.

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

Types shall not be defined in a template-parameterdeclaration.

A type-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 2:

A template argument can be a class template or alias 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_]

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 2: template<typename T> concept C1 = true;template<typename... Ts> concept C2 = true;template<typename T, typename U> concept C3 = true;template<C1 T> struct s1; template<C1... T> struct s2; template<C2... T> struct s3; template<C3<int> T> struct s4; template<C3<int>... T> struct s5; — _end example_]

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

The top-levelcv-qualifier_s_on 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, which is template-argument-equivalent ([temp.type]) to the corresponding template argument after it has been converted to the type of the template-parameter ([temp.arg.nontype]).

No two template parameter objects are template-argument-equivalent.

[Note 3:

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 3: 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 4:

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

[Example 4: template<void v> 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 5: template<int* a> struct R { };template<int b[5]> struct S { };int p; R<&p> w; S<&p> x; int v[5]; R<v> y; S<v> 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 default template argument is a template argument ([temp.arg]) specified after =in a template-parameter.

A default template argument may be specified for any kind of template-parameter (type, non-type, template) that is not a template parameter pack ([temp.variadic]).

A default template argument may be specified in a template declaration.

A default template argument shall not be specified in the template-parameter-list_s_of the definition of a member of a class template that appears outside of the member's class.

A default template argument shall not be specified in a friend class template declaration.

If a friend function template declaration Dspecifies a default template argument, that declaration shall be a definition and there shall be no other declaration of the function template which is reachable from D or from which D is reachable.

The set of default template arguments available 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 6:

template<class T1, class T2 = int> class A;template<class T1 = int, class T2> class A;is equivalent totemplate<class T1 = int, class T2 = int> class A;

— _end example_]

If a template-parameterof a class template, variable template, or alias template has a default template argument, each subsequent template-parametershall either have a default template argument supplied or be a template parameter pack.

If a template-parameter of a primary class template, primary variable template, or alias template is a template parameter pack, it shall be the last template-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 7: template<class T1 = int, class T2> class B; template<class... T, class... U> void f() { } template<class... T, class U> void g() { } — _end example_]

When parsing a default template argument for a non-type template-parameter, the first non-nested > is taken as the end of the template-parameter-listrather than a greater-than operator.

[Example 8: template<int i = 3 > 4 > class X { };template<int i = (3 > 4) > class Y { }; — _end example_]

A template-parameter of a template template-parameteris permitted to have a default template argument.

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

[Example 9: template <template <class TT = float> class T> struct A { inline void f();inline void g();};template <template <class TT> class T> void A<T>::f() { T<> t; } template <template <class TT = char> class T> void A<T>::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 10: 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_]