[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:
- a structural type (see below),
- a type that contains a placeholder type ([dcl.spec.auto]), or
- a placeholder for a deduced class type ([dcl.type.class.deduct]).
The top-levelcv-qualifierson thetemplate-parameterare ignored when determining its type.
A structural type is one of the following:
- a scalar type, or
- an lvalue reference type, or
- a literal class type with the following properties:
- all base classes and non-static data members are public and non-mutable and
- the types of all bases classes and non-static data members are structural types or (possibly multi-dimensional) array thereof.
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
]