Стандарт C++ 11 (1119564), страница 91
Текст из файла (страница 91)
[ Example:template<class T> struct A {~A();};void f(A<int>* p, A<int>* q) {p->A<int>::~A();q->A<int>::~A<int>();}// OK: destructor call// OK: destructor call— end example ]6If the use of a template-argument gives rise to an ill-formed construct in the instantiation of a templatespecialization, the program is ill-formed.7When the template in a template-id is an overloaded function template, both non-template functions in theoverload set and function templates in the overload set for which the template-arguments do not match thetemplate-parameters are ignored.
If none of the function templates have matching template-parameters, theprogram is ill-formed.8A template-argument followed by an ellipsis is a pack expansion (14.5.3).14.3.1Template type arguments1A template-argument for a template-parameter which is a type shall be a type-id.2[ Example:[temp.arg.type]template <class T> class X { };template <class T> void f(T t) { }struct { } unnamed_obj;void f() {struct A { };enum { e1 };typedef struct { } B;B b;X<A> x1;// OKX<A*> x2;// OKX<B> x3;// OKf(e1);// OKf(unnamed_obj);// OKf(b);// OK}— end example ] [ Note: A template type argument may be an incomplete type (3.9). — end note ]3If a declaration acquires a function type through a type dependent on a template-parameter and this causes adeclaration that does not use the syntactic form of a function declarator to have function type, the programis ill-formed.
[ Example:§ 14.3.1© ISO/IEC 2011 – All rights reserved329ISO/IEC 14882:2011(E)template<class T> struct A {static T t;};typedef int function();A<function> a;// ill-formed: would declare A<function>::t// as a static member function— end example ]14.3.21Template non-type arguments[temp.arg.nontype]A template-argument for a non-type, non-template template-parameter shall be one of:— for a non-type template-parameter of integral or enumeration type, a converted constant expression (5.19) of the type of the template-parameter; or— the name of a non-type template-parameter; or— a constant expression (5.19) that designates the address of an object with static storage duration andexternal or internal linkage or a function with external or internal linkage, including function templatesand function template-ids but excluding non-static class members, expressed (ignoring parentheses) as& id-expression, except that the & may be omitted if the name refers to a function or array and shallbe omitted if the corresponding template-parameter is a reference; or— a constant expression that evaluates to a null pointer value (4.10); or— a constant expression that evaluates to a null member pointer value (4.11); or— a pointer to member expressed as described in 5.3.1.2[ Note: A string literal (2.14.5) does not satisfy the requirements of any of these categories and thus is notan acceptable template-argument.
[ Example:template<class T, const char* p> class X {/∗ ... ∗/};X<int, "Studebaker"> x1;// error: string literal as template-argumentconst char p[] = "Vivisectionist";X<int,p> x2;// OK— end example ] — end note ]3[ Note: Addresses of array elements and names or addresses of non-static class members are not acceptabletemplate-arguments. [ Example:template<int* p> class X { };int a[10];struct S { int m; static int s; } s;X<&a[2]> x3;X<&s.m> x4;X<&s.s> x5;X<&S::s> x6;////////error: address of array elementerror: address of non-static membererror: &S::s must be usedOK: address of static member— end example ] — end note ]§ 14.3.2330© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)4[ Note: Temporaries, unnamed lvalues, and named lvalues with no linkage are not acceptable templatearguments when the corresponding template-parameter has reference type.
[ Example:template<const int& CRI> struct B { /∗ ... ∗/ };B<1> b2;// error: temporary would be required for template argumentint c = 1;B<c> b1;// OK— end example ] — end note ]5The following conversions are performed on each expression used as a non-type template-argument.
If anon-type template-argument cannot be converted to the type of the corresponding template-parameter thenthe program is ill-formed.— For a non-type template-parameter of integral or enumeration type, conversions permitted in a converted constant expression (5.19) are applied.— for a non-type template-parameter of type pointer to object, qualification conversions (4.4) and thearray-to-pointer conversion (4.2) are applied; if the template-argument is of type std::nullptr_t, thenull pointer conversion (4.10) is applied.
[ Note: In particular, neither the null pointer conversion fora zero-valued integral constant expression (4.10) nor the derived-to-base conversion (4.10) are applied.Although 0 is a valid template-argument for a non-type template-parameter of integral type, it is nota valid template-argument for a non-type template-parameter of pointer type. However, both (int*)0and nullptr are valid template-arguments for a non-type template-parameter of type “pointer to int.”— end note ]— For a non-type template-parameter of type reference to object, no conversions apply.
The type referredto by the reference may be more cv-qualified than the (otherwise identical) type of the templateargument. The template-parameter is bound directly to the template-argument, which shall be anlvalue.— For a non-type template-parameter of type pointer to function, the function-to-pointer conversion (4.3)is applied; if the template-argument is of type std::nullptr_t, the null pointer conversion (4.10) isapplied. If the template-argument represents a set of overloaded functions (or a pointer to such), thematching function is selected from the set (13.4).— For a non-type template-parameter of type reference to function, no conversions apply.
If the templateargument represents a set of overloaded functions, the matching function is selected from the set (13.4).— For a non-type template-parameter of type pointer to member function, if the template-argument is oftype std::nullptr_t, the null member pointer conversion (4.11) is applied; otherwise, no conversionsapply. If the template-argument represents a set of overloaded member functions, the matching memberfunction is selected from the set (13.4).— For a non-type template-parameter of type pointer to data member, qualification conversions (4.4) areapplied; if the template-argument is of type std::nullptr_t, the null member pointer conversion (4.11)is applied.[ Example:template<const int* pci> struct X { /∗ ... ∗/ };int ai[10];X<ai> xi;// array to pointer and qualification conversionsstruct Y { /∗ ...
∗/ };§ 14.3.2© ISO/IEC 2011 – All rights reserved331ISO/IEC 14882:2011(E)template<const Y& b> struct Z { /∗ ... ∗/ };Y y;Z<y> z;// no conversion, but note extra cv-qualificationtemplate<int (&pa)[5]> struct W { /∗ ... ∗/ };int b[5];W<b> w;// no conversionvoid f(char);void f(int);template<void (*pf)(int)> struct A { /∗ ... ∗/ };A<&f> a;// selects f(int)— end example ]14.3.3Template template arguments[temp.arg.template]1A template-argument for a template template-parameter shall be the name of a class template or an aliastemplate, expressed as id-expression. When the template-argument names a class template, only primaryclass templates are considered when matching the template template argument with the correspondingparameter; partial specializations are not considered even if their parameter lists match that of the templatetemplate parameter.2Any partial specializations (14.5.5) associated with the primary class template are considered when a specialization based on the template template-parameter is instantiated.
If a specialization is not visible at thepoint of instantiation, and it would have been selected had it been visible, the program is ill-formed; nodiagnostic is required. [ Example:template<class T> class A {// primary templateint x;};template<class T> class A<T*> { // partial specializationlong x;};template<template<class U> class V> class C {V<int> y;V<int*> z;};C<A> c;// V<int> within C<A> uses the primary template,// so c.y.x has type int// V<int*> within C<A> uses the partial specialization,// so c.z.x has type long— end example ][ Example:template<class T> class A { /∗ ... ∗/ };template<class T, class U = T> class B { /∗ ...
∗/ };template <class ... Types> class C { /∗ ... ∗/ };template<template<class> class P> class X { /∗ ... ∗/ };template<template<class ...> class Q> class Y { /∗ ... ∗/ };§ 14.3.3332© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)X<A> xa;X<B> xb;X<C> xc;// OK// ill-formed: default arguments for the parameters of a template argument are ignored// ill-formed: a template parameter pack does not match a template parameterY<A> ya;Y<B> yb;Y<C> yc;// OK// OK// OK— end example ]3A template-argument matches a template template-parameter (call it P) when each of the template parametersin the template-parameter-list of the template-argument’s corresponding class template or alias template (callit A) matches the corresponding template parameter in the template-parameter-list of P.
When P’s templateparameter-list contains a template parameter pack (14.5.3), the template parameter pack will match zeroor more template parameters or template parameter packs in the template-parameter-list of A with thesame type and form as the template parameter pack in P (ignoring whether those template parameters aretemplate parameter packs) [ Example:template <class T> struct eval;template <template <class, class...> class TT, class T1, class... Rest>struct eval<TT<T1, Rest...>> { };templatetemplatetemplatetemplatetemplate<class T1> struct A;<class T1, class T2> struct B;<int N> struct C;<class T1, int N> struct D;<class T1, class T2, int N = 17> struct E;eval<A<int>> eA;eval<B<int, float>> eB;eval<C<17>> eC;eval<D<int, 17>> eD;eval<E<int, float>> eE;//////////OK: matchesOK: matcheserror: C doeserror: D doeserror: E doespartial specialization ofpartial specialization ofnot match TT in partialnot match TT in partialnot match TT in partialevalevalspecializationspecializationspecialization— end example ]14.41Type equivalence[temp.type]Two template-ids refer to the same class or function if— their template-names, operator-function-ids, or literal-operator-ids refer to the same template and— their corresponding type template-arguments are the same type and— their corresponding non-type template arguments of integral or enumeration type have identical valuesand— their corresponding non-type template-arguments of pointer type refer to the same external object orfunction or are both the null pointer value and— their corresponding non-type template-arguments of pointer-to-member type refer to the same classmember or are both the null member pointer value and— their corresponding non-type template-arguments of reference type refer to the same external objector function and§ 14.4© ISO/IEC 2011 – All rights reserved333ISO/IEC 14882:2011(E)— their corresponding template template-arguments refer to the same template.[ Example:template<class E, int size> class buffer { /∗ ...
∗/ };buffer<char,2*512> x;buffer<char,1024> y;declares x and y to be of the same type, andtemplate<class T, void(*err_fct)()> class list { /∗ ... ∗/ };list<int,&error_handler1> x1;list<int,&error_handler2> x2;list<int,&error_handler2> x3;list<char,&error_handler2> x4;declares x2 and x3 to be of the same type. Their type differs from the types of x1 and x4.template<class T> struct X { };template<class> struct Y { };template<class T> using Z = Y<T>;X<Y<int> > y;X<Z<int> > z;declares y and z to be of the same type.