-1- A template defines a family of classes or functions.
template-declaration: exportopt template < template-parameter-list > declaration
The declaration in a template-declaration shalltemplate-parameter-list: template-parameter template-parameter-list , template-parameter
-2- A template-declaration can appear only as a namespace scope or class scope declaration. In a function template declaration, the declarator-id shall be a template-name (i.e., not a template-id). [Note: in a class template declaration, if the declarator-id is a template-id, the declaration declares a class template partial specialization (temp.class.spec). ]
-3- In a template-declaration, explicit specialization, or explicit instantiation the init-declarator-list in the declaration shall contain at most one declarator. When such a declaration is used to declare a class template, no declarator is permitted.
-4- A template name may have linkage (basic.link). A template, a template explicit specialization (temp.expl.spec), or a class template partial specialization shall not have C linkage. If the linkage of one of these is something other than C or C++, the behavior is implementation-defined. Template definitions shall obey the one definition rule (basic.def.odr). [Note: default arguments for function templates and for member functions of class templates are considered definitions for the purpose of template instantiation (temp.decls) and must also obey the one definition rule. ]
-5- A class template shall not have the same name as any other template, class, function, object, enumeration, enumerator, namespace, or type in the same scope (basic.scope), except as specified in (temp.class.spec). Except that a function template can be overloaded either by (non-template) functions with the same name or by other function templates with the same name (temp.over), a template name declared in namespace scope or in class scope shall be unique in that scope.
-6- A namespace-scope declaration or definition of a non-inline function template, a non-inline member function template, a non-inline member function of a class template or a static data member of a class template may be preceded by the export keyword. If such a template is defined in the same translation unit in which it is declared as exported, the definition is considered to be exported. The first declaration of the template containing the export keyword must not follow the definition.
-7- Declaring a class template exported is equivalent to declaring all of its non-inline function members, static data members, member classes, member class templates and non-inline function member templates which are defined in that translation unit exported.
-8- Templates defined in an unnamed namespace shall not be exported. A template shall be exported only once in a program. An implementation is not required to diagnose a violation of this rule. A non-exported template that is neither explicitly specialized nor explicitly instantiated must be defined in every translation unit in which it is implicitly instantiated (temp.inst) or explicitly instantiated (temp.explicit); no diagnostic is required. An exported template need only be declared (and not necessarily defined) in a translation unit in which it is instantiated. A template function declared both exported and inline is just inline and not exported.
-9-
[Note:
an implementation may require that a translation unit containing the
definition of an exported template be compiled before any
translation unit containing an instantiation of that template.
]
14.1 - Template parameters [temp.param]
-1- The syntax for template-parameters is:
template-parameter: type-parameter parameter-declaration
type-parameter: class identifieropt class identifieropt = type-id typename identifieropt typename identifieropt = type-id template < template-parameter-list > class identifieropt template < template-parameter-list > class identifieropt = id-expression
-2- There is no semantic difference between class and typename in a template-parameter. typename followed by an unqualified-id names a template type parameter. typename followed by a qualified-name denotes the type in a non-type *
[Footnote: Since template template-parameters and template template-arguments are treated as types for descriptive purposes, the terms non-type parameter and non-type argument are used to refer to non-type, non-template parameters and arguments. --- end foonote]parameter-declaration. A storage class shall not be specified in a template-parameter declaration. [Note: a template parameter may be a class 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; //... };
-3- A type-parameter defines its identifier to be a type-name (if declared with class or typename) or template-name (if declared with template) in the scope of the template declaration. [Note: because of the name lookup rules, a template-parameter that could be interpreted as either a non-type template-parameter or a type-parameter (because its identifier is the name of an already existing class) is taken as a type-parameter. For example,
Here, the template f has a type-parameter called T, rather than an unnamed non-type template-parameter of class T. ]class T { /* ... */ }; int i; template<class T, T i> void f(T t) { T t1 = i; //template-parameters T and i ::T t2 = ::i; // global namespace members T and i }
-4- A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
-5- [Note: other types are disallowed either explicitly below or implicitly by the rules governing the form of template-arguments (temp.arg). ] The top-level cv-qualifiers on the template-parameter are ignored when determining its type.
-6- A non-type non-reference template-parameter is not an lvalue. It shall not be assigned to or in any other way have its value changed. A non-type non-reference template-parameter cannot have its address taken. When a non-type non-reference template-parameter is used as an initializer for a reference, a temporary is always used. [Example:
template<const X& x, int i> void f() { i++; //error: change of template-parameter value &x; // OK &i; // error: address of non-reference template-parameter int& ri = i; // error: non-const reference bound to temporary const int& cri = i; // OK: const reference bound to temporary }
-7- A non-type template-parameter shall not be declared to have floating point, class, or void type. [Example:
template<double d> class X; //error template<double* pd> class Y; // OK template<double& rd> class Z; // OK
-8- A non-type template-parameter of type ``array of T'' or ``function returning T'' is adjusted to be of type ``pointer to T'' or ``pointer to function returning T'', respectively. [Example:
template<int *a> struct R { /* ... */ }; template<int b[5]> struct S { /* ... */ }; int *p; R<p> w; //OK S<p> x; // OK due to parameter adjustment int v[5]; R<v> y; // OK due to implicit argument conversion S<v> z; // OK due to both adjustment and conversion
-9- 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). A default template-argument may be specified in a class template declaration or a class template definition. A default template-argument shall not be specified in a function template declaration or a function template definition, nor in the template-parameter-list of the definition of a member of a class template.
-10- The set of default template-arguments available for use with a template declaration or definition is obtained by merging the default arguments from the definition (if in scope) and all declarations in scope in the same way default function arguments are (dcl.fct.default). [Example:
is equivalent totemplate<class T1, class T2 = int> class A; template<class T1 = int, class T2> class A;
template<class T1 = int, class T2 = int> class A;
-11- If a template-parameter has a default template-argument, all subsequent template-parameters shall have a default template-argument supplied. [Example:
template<class T1 = int, class T2> class B; //error
-12- A template-parameter may not be given default arguments by two different declarations in the same scope. [Example:
template<class T = int> class X; template<class T = int> class X { /*... */ }; //error
-13- The scope of a template-parameter extends from its point of declaration until the end of its template. In particular, a template-parameter can be used in the declaration of subsequent template-parameters and their default arguments. [Example:
template<class T, T* p, class U = T> class X { /* ... */ }; template<class T> void f(T* p = new T);
-14- A template-parameter cannot be used in preceding template-parameters or their default arguments.
-15- 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-list rather than a greater-than operator. [Example:
template<int i = 3 > 4 > //syntax error class X { /* ... */ }; template<int i = (3 > 4) > // OK class Y { /* ... */ };
-1- A template specialization (temp.spec) can be referred to by a template-id:
template-id: template-name < template-argument-listopt >
template-name: identifier
template-argument-list: template-argument template-argument-list , template-argument
[Note: the name lookup rules (basic.lookup) are used to associate the use of a name with a template declaration; that is, to identify a name as a template-name. ]template-argument: assignment-expression type-id id-expression
-2- For a template-name to be explicitly qualified by the template arguments, the name must be known to refer to a template.
-3- After name lookup (basic.lookup) finds that a name is a template-name, if this name is followed by a <, the < is always taken as the beginning of a template-argument-list and never as a name followed by the less-than operator. When parsing a template-id, the first non-nested >*
[Footnote: A > that encloses the type-id of a dynamic_cast, static_cast, reinterpret_cast or const_cast, or which encloses the template-arguments of a subsequent template-id, is considered nested for the purpose of this description. --- end foonote]is taken as the end of the template-argument-list rather than a greater-than operator. [Example:
template<int i> class X { /* ... */ }; X< 1>2 > x1; //syntax error X<(1>2)> x2; // OK template<class T> class Y { /* ... */ }; Y< X<1> > x3; // OK Y<X<6>> 1> > x4; // OK: Y< X< (6>>1) > >
-4- When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (temp.dep), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template. [Example:
class X { public: template<size_t> X* alloc(); template<size_t> static X* adjust(); }; template<class T> void f(T* p) { T* p1 = p->alloc<200>(); //ill-formed: < means less than T* p2 = p->template alloc<200>(); // OK: < starts template argument list T::adjust<100>(); // ill-formed: < means less than T::template adjust<100>(); // OK: < starts explicit qualification }
-5- If a name prefixed by the keyword template is not the name of a member template, the program is ill-formed. [Note: the keyword template may not be applied to non-template members of class templates. ]
-6-
A
template-id
that names a class template specialization is a
class-name
(clause class).
14.3 - Template arguments [temp.arg]
-1- There are three forms of template-argument, corresponding to the three forms of template-parameter: type, non-type and template. The type and form of each template-argument specified in a template-id shall match the type and form specified for the corresponding parameter declared by the template in its template-parameter-list. [Example:
template<class T> class Array { T* v; int sz; public: explicit Array(int); T& operator[](int); T& elem(int i) { return v[i]; } //... };
Array<int> v1(20); typedef complex<double> dcomplex; //complex is a standard // library template Array<dcomplex> v2(30); Array<dcomplex> v3(40); void bar() { v1[3] = 7; v2[3] = v3.elem(4) = dcomplex(7,8); }
-2- In a template-argument, an ambiguity between a type-id and an expression is resolved to a type-id, regardless of the form of the corresponding template-parameter.*
[Footnote: There is no such ambiguity in a default template-argument because the form of the template-parameter determines the allowable forms of the template-argument. --- end foonote][Example:
template<class T> void f(); template<int I> void f(); void g() { f<int()>(); //int() is a type-id: call the first f() }
-3- The name of a template-argument shall be accessible at the point where it is used as a template-argument. [Note: if the name of the template-argument is accessible at the point where it is used as a template-argument, there is no further access restriction in the resulting instantiation where the corresponding template-parameter name is used. ] [Example:
template<class T> class X { static T t; }; class Y { private: struct S { /* ... */ }; X<S> x; //OK: S is accessible // X<Y::S> has a static member of type Y::S // OK: even though Y::S is private }; X<Y::S> y; // error: S not accessible
-4- When default template-arguments are used, a template-argument list can be empty. In that case the empty <> brackets shall still be used as the template-argument-list. [Example:
template<class T = char> class String; String<>* p; //OK: String<char> String* q; // syntax error
-5- An explicit destructor call (class.dtor) for an object that has a type that is a class template specialization may explicitly specify the template-arguments. [Example:
template<class T> struct A { ~A(); }; void f(A<int>* p, A<int>* q) { p->A<int>::~A(); //OK: destructor call q->A<int>::~A<int>(); // OK: destructor call }
-6- If the use of a template-argument gives rise to an ill-formed construct in the instantiation of a template specialization, the program is ill-formed.
-7-
When the template in a
template-id
is an overloaded function template, both non-template functions in the overload
set and function templates in the overload set for
which the
template-arguments
do not match the
template-parameters
are ignored.
If none of the function templates have matching
template-parameters,
the program is ill-formed.
14.3.1 - Template type arguments [temp.arg.type]
-1- A template-argument for a template-parameter which is a type shall be a type-id.
-2- A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter. [Example:
template <class T> class X { /* ... */ }; void f() { struct S { /* ... */ }; X<S> x3; //error: local type used as template-argument X<S*> x4; // error: pointer to local type used as template-argument }
-3- If a declaration acquires a function type through a type dependent on a template-parameter and this causes a declaration that does not use the syntactic form of a function declarator to have function type, the program is ill-formed. [Example:
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
-1- A template-argument for a non-type, non-template template-parameter shall be one of:
-2- [Note: A string literal (lex.string) is not an acceptable template-argument because a string literal is an object with internal linkage. [Example:
template<class T, char* p> class X { //... X(); X(const char* q) { /* ... */ } }; X<int,"Studebaker"> x1; // error: string literal as template-argument char p[] = "Vivisectionist"; X<int,p> x2; // OK
-3- [Note: Addresses of array elements and names or addresses of non-static class members are not acceptable template-arguments. [Example:
template<int* p> class X { }; int a[10]; struct S { int m; static int s; } s; X<&a[2]> x3; //error: address of array element X<&s.m> x4; // error: address of non-static member X<&s.s> x5; // error: &S::s must be used X<&S::s> x6; // OK: address of static member
-4- [Note: Temporaries, unnamed lvalues, and named lvalues that do not have external linkage are not acceptable template-arguments 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 argument int c = 1; B<c> b1; // OK
-5- The following conversions are performed on each expression used as a non-type template-argument. If a non-type template-argument cannot be converted to the type of the corresponding template-parameter then the program is ill-formed.
template<const int* pci> struct X { /* ... */ }; int ai[10]; X<ai> xi; //array to pointer and qualification conversions
struct Y { /* ... */ }; template<const Y& b> struct Z { /* ... */ }; Y y; Z<y> z; //no conversion, but note extra cv-qualification
template<int (&pa)[5]> struct W { /* ... */ }; int b[5]; W<b> w; //no conversion
void f(char); void f(int); template<void (*pf)(int)> struct A { /* ... */ }; A<&f> a; //selects f(int)
-1- A template-argument for a template template-parameter shall be the name of a class template, expressed as id-expression. Only primary class templates are considered when matching the template template argument with the corresponding parameter; partial specializations are not considered even if their parameter lists match that of the template template parameter.
-2- Any partial specializations (temp.class.spec) 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 the point of instantiation, and it would have been selected had it been visible, the program is ill-formed; no diagnostic is required. [Example:
template<class T> class A { //primary template int x; }; template<class T> class A<T*> { // partial specialization long 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
-1- Two template-ids refer to the same class or function if their template names are identical, they refer to the same template, their type template-arguments are the same type, their non-type template-arguments of integral or enumeration type have identical values, their non-type template-arguments of pointer or reference type refer to the same external object or function, and their template template-arguments refer to the same template. [Example:
declares x and y to be of the same type, andtemplate<class E, int size> class buffer { /* ... */ }; buffer<char,2*512> x; buffer<char,1024> y;
declares x2 and x3 to be of the same type. Their type differs from the types of x1 and x4. ]template<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;
-1- A template-id, that is, the template-name followed by a template-argument-list shall not be specified in the declaration of a primary template declaration. [Example:
template<class T1, class T2, int I> class A<T1, T2, I> { }; //error template<class T1, int I> void sort<T1, I>(T1 data[I]); // error
-2-
For purposes of name lookup and instantiation,
default arguments of function templates and default arguments of
member functions of class templates are considered definitions;
each default argument is a separate definition which is unrelated to
the function template definition or to any other default arguments.
14.5.1 - Class templates [temp.class]
-1-
A class
template
defines the layout and operations
for an unbounded set of related types.
[Example:
a single class template
List
might provide a common definition for
list of
int,
list of
float,
and list of pointers to
Shapes.
]
-2- [Example: An array class template might be declared like this:
The prefix template <class T> specifies that a template is being declared and that a type-name T will be used in the declaration. In other words, Array is a parameterized type with T as its parameter. ]template<class T> class Array { T* v; int sz; public: explicit Array(int); T& operator[](int); T& elem(int i) { return v[i]; } //... };
-3- When a member function, a member class, a static data member or a member template of a class template is defined outside of the class template definition, the member definition is defined as a template definition in which the template-parameters are those of the class template. The names of the template parameters used in the definition of the member may be different from the template parameter names used in the class template definition. The template argument list following the class template name in the member definition shall name the parameters in the same order as the one used in the template parameter list of the member. [Example:
template<class T1, class T2> struct A { void f1(); void f2(); }; template<class T2, class T1> void A<T2,T1>::f1() { } //OK template<class T2, class T1> void A<T1,T2>::f2() { } // error
-4-
In a redeclaration, partial specialiation, 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).
14.5.1.1 - Member functions of class templates [temp.mem.func]
-1- A member function template may be defined outside of the class template definition in which it is declared. [Example:
declares three function templates. The subscript function might be defined like this:template<class T> class Array { T* v; int sz; public: explicit Array(int); T& operator[](int); T& elem(int i) { return v[i]; } //... };
template<class T> T& Array<T>::operator[](int i) { if (i<0 || sz<=i) error("Array: range error"); return v[i]; }
-2- The template-arguments for a member function of a class template are determined by the template-arguments of the type of the object for which the member function is called. [Example: the template-argument for Array<T>::operator[]() will be determined by the Array to which the subscripting operation is applied.
Array<int> v1(20); Array<dcomplex> v2(30); v1[3] = 7; //Array<int>::operator[]() v2[3] = dcomplex(7,8); // Array<dcomplex>::operator[]()
-1- A class member of a class template may be defined outside the class template definition in which it is declared. [Note: the class member must be defined before its first use that requires an instantiation (temp.inst). For example,
template<class T> struct A { class B; }; A<int>::B* b1; //OK: requires A to be defined but not A::B template<class T> class A<T>::B { }; A<int>::B b2; // OK: requires A::B to be defined
-1- A definition for a static data member may be provided in a namespace scope enclosing the definition of the static member's class template. [Example:
template<class T> class X { static T s; }; template<class T> T X<T>::s = 0;
-1- A template can be declared within a class or class template; such a template is called a member template. A member template can be defined within or outside its class definition or class template definition. A member template of a class template that is defined outside of its class template definition shall be specified with the template-parameters of the class template followed by the template-parameters of the member template. [Example:
template<class T> class string { public: template<class T2> int compare(const T2&); template<class T2> string(const string<T2>& s) { /* ... */ } //... }; template<class T> template<class T2> int string<T>::compare(const T2& s) { // ... }
-2- A local class shall not have member templates. Access control rules (clause class.access) apply to member template names. A destructor shall not be a member template. A normal (non-template) member function with a given name and type and a member function template of the same name, which could be used to generate a specialization of the same type, can both be declared in a class. When both exist, a use of that name and type refers to the non-template member unless an explicit template argument list is supplied. [Example:
template <class T> struct A { void f(int); template <class T2> void f(T2); }; template <> void A<int>::f(int) { } //non-template member template <> template <> void A<int>::f<>(int) { } // template member
int main() { A<char> ac; ac.f(1); //non-template ac.f('c'); // template ac.f<>(1); // template }
-3- A member function template shall not be virtual. [Example:
template <class T> struct AA { template <class C> virtual void g(C); //error virtual void f(); // OK };
-4- A specialization of a member function template does not override a virtual function from a base class. [Example:
class B { virtual void f(int); };
class D : public B { template <class T> void f(T); //does not override B::f(int) void f(int i) { f<>(i); } // overriding function that calls // the template instantiation };
-5- A specialization of a template conversion function is referenced in the same way as a non-template conversion function that converts to the same type. [Example:
struct A { template <class T> operator T*(); }; template <class T> A::operator T*(){ return 0; } template <> A::operator char*(){ return 0; } //specialization template A::operator void*(); // explicit instantiation
int main() { A a; int* ip; ip = a.operator int*(); //explicit call to template operator // A::operator int*() }
-6- A specialization of a template conversion function is not found by name lookup. Instead, any template conversion functions visible in the context of the use are considered. For each such operator, if argument deduction succeeds (temp.deduct.conv), the resulting specialization is used as if found by name lookup.
-7- A using-declaration in a derived class cannot refer to a specialization of a template conversion function in a base class.
-8-
Overload resolution (over.ics.rank) and partial ordering
(temp.func.order) are used to select the best conversion function
among multiple template conversion functions and/or non-template
conversion functions.
14.5.3 - Friends [temp.friend]
-1- A friend of a class or class template can be a function template or class template, a specialization of a function template or class template, or an ordinary (nontemplate) function or class. For a friend function declaration that is not a template declaration:
template<class T> class task; template<class T> task<T>* preempt(task<T>*);
Here, each specialization of the task class template has the function next_time as a friend; because process does not have explicit template-arguments, each specialization of the task class template has an appropriately typed function process as a friend, and this friend is not a function template specialization; because the friend preempt has an explicit template-argument <T>, each specialization of the task class template has the appropriate specialization of the function template preempt as a friend; and each specialization of the task class template has all specializations of the function template func as friends. Similarly, each specialization of the task class template has the class template specialization task<int> as a friend, and has all specializations of the class template frd as friends.template<class T> class task { //... friend void next_time(); friend void process(task<T>*); friend task<T>* preempt<T>(task<T>*); template<class C> friend int func(C); friend class task<int>; template<class P> friend class frd; // ... };
-2- A friend function declaration that is not a template declaration and in which the name of the friend is an unqualified template-id shall refer to a specialization of a function template declared in the nearest enclosing namespace scope. [Example:
namespace N { template <class T> void f(T); void g(int); namespace M { template <class T> void h(T); template <class T> void i(T); struct A { friend void f<>(int); //ill-formed - N::f friend void h<>(int); // OK - M::h friend void g(int); // OK - new decl of M::g template <class T> void i(T); friend void i<>(int); // ill-formed - A::i }; } }
-3- A friend template may be declared within a class or class template. A friend function template may be defined within a class or class template, but a friend class template may not be defined in a class or class template. In these cases, all specializations of the friend class or friend function template are friends of the class or class template granting friendship. [Example:
class A { template<class T> friend class B; //OK template<class T> friend void f(T){ /* ... */ } // OK };
-4- A template friend declaration specifies that all specializations of that template, whether they are implicitly instantiated (temp.inst), partially specialized (temp.class.spec) or explicitly specialized (temp.expl.spec), are friends of the class containing the template friend declaration. [Example:
class X { template<class T> friend struct A; class Y { }; }; template<class T> struct A { X::Y ab; }; //OK template<class T> struct A<T*> { X::Y ab; }; // OK
-5- When a function is defined in a friend function declaration in a class template, the function is defined at each instantiation of the class template. The function is defined even if it is never used. The same restrictions on multiple declarations and definitions which apply to non-template function declarations and definitions also apply to these implicit definitions. [Note: if the function definition is ill-formed for a given specialization of the enclosing class template, the program is ill-formed even if the function is never used. ]
-6- A member of a class template may be declared to be a friend of a non-template class. In this case, the corresponding member of every specialization of the class template is a friend of the class granting friendship. [Example:
template<class T> struct A { struct B { }; void f(); }; class C { template<class T> friend struct A<T>::B; template<class T> friend void A<T>::f(); };
-7- [Note: a friend declaration may first declare a member of an enclosing namespace scope (temp.inject). ]
-8- A friend template shall not be declared in a local class.
-9- Friend declarations shall not declare partial specializations. [Example:
template<class T> class A { }; class X { template<class T> friend class A<T*>; //error };
-10-
When a friend declaration refers to a specialization of a function
template, the function parameter declarations shall not include
default arguments, nor shall the inline specifier be used in such a
declaration.
14.5.4 - Class template partial specializations [temp.class.spec]
-1- A primary class template declaration is one in which the class template name is an identifier. A template declaration in which the class template name is a template-id, is a partial specialization of the class template named in the template-id. A partial specialization of a class template provides an alternative definition of the template that is used instead of the primary definition when the arguments in a specialization match those given in the partial specialization (temp.class.spec.match). The primary template shall be declared before any specializations of that template. If a template is partially specialized then that partial specialization shall be declared before the first use of that partial specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.
-2- When a partial specialization is used within the instantiation of an exported template, and the unspecialized template name is non-dependent in the exported template, a declaration of the partial specialization must be declared before the definition of the exported template, in the translation unit containing that definition. A similar restriction applies to explicit specialization; see temp.spec.
-3- Each class template partial specialization is a distinct template and definitions shall be provided for the members of a template partial specialization (temp.class.spec.mfunc).
-4- [Example:
The first declaration declares the primary (unspecialized) class template. The second and subsequent declarations declare partial specializations of the primary template. ]template<class T1, class T2, int I> class A { }; //#1 template<class T, int I> class A<T, T*, I> { }; // #2 template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3 template<class T> class A<int, T*, 5> { }; // #4 template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5
-5- The template parameters are specified in the angle bracket enclosed list that immediately follows the keyword template. For partial specializations, the template argument list is explicitly written immediately following the class template name. For primary templates, this list is implicitly described by the template parameter list. Specifically, the order of the template arguments is the sequence in which they appear in the template parameter list. [Example: the template argument list for the primary template in the example above is <T1, T2, I>. ] [Note: the template argument list shall not be specified in the primary template declaration. For example,
template<class T1, class T2, int I> class A<T1, T2, I> { }; //error
-6- A class template partial specialization may be declared or redeclared in any namespace scope in which its definition may be defined (temp.class and temp.mem). [Example:
template<class T> struct A { class C { template<class T2> struct B { }; }; }; //partial specialization of A<T>::C::B<T2> template<class T> template<class T2> struct A<T>::C::B<T2*> { }; A<short>::C::B<int*> absip; // uses partial specialization
-7- Partial specialization declarations themselves are not found by name lookup. Rather, when the primary template name is used, any previously declared partial specializations of the primary template are also considered. One consequence is that a using-declaration which refers to a class template does not restrict the set of partial specializations which may be found through the using-declaration. [Example:
namespace N { template<class T1, class T2> class A { }; //primary template } using N::A; // refers to the primary template namespace N { template<class T> class A<T, T*> { }; // partial specialization } A<int,int*> a; // uses the partial specialization, which is found through // the using declaration which refers to the primary template
-8- A non-type argument is non-specialized if it is the name of a non-type parameter. All other non-type arguments are specialized.
-9- Within the argument list of a class template partial specialization, the following restrictions apply:
template <int I, int J> struct A {}; template <int I> struct A<I+5, I*2> {}; //error template <int I, int J> struct B {}; template <int I> struct B<I, I> {}; // OK
template <class T, T t> struct C {}; template <class T> struct C<T, 1>; //error template< int X, int (*array_ptr)[X] > class A {}; int array[5]; template< int X > class A<X,&array> { }; // error
-10- The template parameter list of a specialization shall not contain default template argument values.*
[Footnote: There is no way in which they could be used. --- end foonote]
-1- When a class template is used in a context that requires an instantiation of the class, it is necessary to determine whether the instantiation is to be generated using the primary template or one of the partial specializations. This is done by matching the template arguments of the class template specialization with the template argument lists of the partial specializations.
-2- A partial specialization matches a given actual template argument list if the template arguments of the partial specialization can be deduced from the actual template argument list (temp.deduct). [Example:
A<int, int, 1> a1; //uses #1 A<int, int*, 1> a2; // uses #2, T is int, I is 1 A<int, char*, 5> a3; // uses #4, T is char A<int, char*, 1> a4; // uses #5, T1 is int, T2 is char, I is 1 A<int*, int*, 2> a5; // ambiguous: matches #3 and #5
-3- A non-type template argument can also be deduced from the value of an actual template argument of a non-type parameter of the primary template. [Example: the declaration of a2 above. ]
-4-
In a type name that refers to a class template specialization, (e.g.,
A<int, int, 1>)
the argument list must match the template parameter list of the primary
template.
The template arguments of a specialization are deduced from the arguments
of the primary template.
14.5.4.2 - Partial ordering of class template specializations [temp.class.order]
-1- For two class template partial specializations, the first is at least as specialized as the second if, given the following rewrite to two function templates, the first function template is at least as specialized as the second according to the ordering rules for function templates (temp.func.order):
-2- [Example:
The partial specialization #2 is more specialized than the partial specialization #1 because the function template #B is more specialized than the function template #A according to the ordering rules for function templates. ]template<int I, int J, class T> class X { }; template<int I, int J> class X<I, J, int> { }; //#1 template<int I> class X<I, I, int> { }; // #2 template<int I, int J> void f(X<I, J, int>); // #A template<int I> void f(X<I, I, int>); // #B
-1- The template parameter list of a member of a class template partial specialization shall match the template parameter list of the class template partial specialization. The template argument list of a member of a class template partial specialization shall match the template argument list of the class template partial specialization. A class template specialization is a distinct template. The members of the class template partial specialization are unrelated to the members of the primary template. Class template partial specialization members that are used in a way that requires a definition shall be defined; the definitions of members of the primary template are never used as definitions for members of a class template partial specialization. An explicit specialization of a member of a class template partial specialization is declared in the same way as an explicit specialization of the primary template. [Example:
//primary template template<class T, int I> struct A { void f(); }; template<class T, int I> void A<T,I>::f() { }
//class template partial specialization template<class T> struct A<T,2> { void f(); void g(); void h(); }; // member of class template partial specialization template<class T> void A<T,2>::g() { }
//explicit specialization template<> void A<char,2>::h() { } int main() { A<char,0> a0; A<char,2> a2; a0.f(); // OK, uses definition of primary template's member a2.g(); // OK, uses definition of // partial specialization's member a2.h(); // OK, uses definition of // explicit specialization's member a2.f(); // ill-formed, no definition of f for A<T,2> // the primary template is not used here }
-2- If a member template of a class template is partially specialized, the member template partial specializations are member templates of the enclosing class template; if the enclosing class template is instantiated (temp.inst, temp.explicit), a declaration for every member template partial specialization is also instantiated as part of creating the members of the class template specialization. If the primary member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the partial specializations of the member template are ignored for this specialization of the enclosing class template. If a partial specialization of the member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the primary member template and its other partial specializations are still considered for this specialization of the enclosing class template. [Example:
template<class T> struct A { template<class T2> struct B {}; //#1 template<class T2> struct B<T2*> {}; // #2 }; template<> template<class T2> struct A<short>::B {}; // #3 A<char>::B<int*> abcip; // uses #2 A<short>::B<int*> absip; // uses #3 A<char>::B<int> abci; // uses #1
-1- A function template defines an unbounded set of related functions. [Example: a family of sort functions might be declared like this:
template<class T> class Array { }; template<class T> void sort(Array<T>&);
-2- A function template can be overloaded with other function templates and with normal (non-template) functions. A normal function is not related to a function template (i.e., it is never considered to be a specialization), even if it has the same name and type as a potentially generated function template specialization.*
[Footnote: That is, declarations of non-template functions do not merely guide overload resolution of template functions with the same name. If such a non-template function is used in a program, it must be defined; it will not be implicitly instantiated using the function template definition. --- end foonote]
-1- It is possible to overload function templates so that two different function template specializations have the same type. [Example:
// file1.c // file2.c template<class T> template<class T> void f(T*); void f(T); void g(int* p) { void h(int* p) { f(p); // call f(p); // call // f<int>(int*) // f<int*>(int*) } }
-2- Such specializations are distinct functions and do not violate the one definition rule (basic.def.odr).
-3- The signature of a function template specialization consists of the signature of the function template and of the actual template arguments (whether explicitly specified or deduced).
-4- The signature of a function template consists of its function signature, its return type and its template parameter list. The names of the template parameters are significant only for establishing the relationship between the template parameters and the rest of the signature. [Note: two distinct function templates may have identical function return types and function parameter lists, even if overload resolution alone cannot distinguish them.
template<class T> void f(); template<int I> void f(); //OK: overloads the first template // distinguishable with an explicit template argument list
-5- When an expression that references a template parameter is used in the function parameter list or the return type in the declaration of a function template, the expression that references the template parameter is part of the signature of the function template. This is necessary to permit a declaration of a function template in one translation unit to be linked with another declaration of the function template in another translation unit and, conversely, to ensure that function templates that are intended to be distinct are not linked with one another. [Example:
template <int I, int J> A<I+J> f(A<I>, A<J>); //#1 template <int K, int L> A<K+L> f(A<K>, A<L>); // same as #1 template <int I, int J> A<I-J> f(A<I>, A<J>); // different from #1
-6- Two expressions involving template parameters are considered equivalent if two function definitions containing the expressions would satisfy the one definition rule (basic.def.odr), except that the tokens used to name the template parameters may differ as long as a token used to name a template parameter in one expression is replaced by another token that names the same template parameter in the other expression. [Example:
template <int I, int J> void f(A<I+J>); //#1 template <int K, int L> void f(A<K+L>); // same as #1
-7- Two function templates are equivalent if they are declared in the same scope, have the same name, have identical template parameter lists, and have return types and parameter lists that are equivalent using the rules described above to compare expressions involving non-type template parameters. Two function templates are functionally equivalent if they are equivalent except that one or more non-type expressions that involve template parameters in the return types and parameter lists are functionally equivalent using the rules described above to compare expressions involving non-type template parameters. If a program contains declarations of function templates that are functionally equivalent but not equivalent, the program is ill-formed; no diagnostic is required.
-8- [Note: This rule guarantees that equivalent declarations will be linked with one another, while not requiring implementations to use heroic efforts to guarantee that functionally equivalent declarations will be treated as distinct. For example, the last two declarations are functionally equivalent and would cause a program to be ill-formed:
//Guaranteed to be the same template <int I> void f(A<I>, A<I+10>); template <int I> void f(A<I>, A<I+10>); // Guaranteed to be different template <int I> void f(A<I>, A<I+10>); template <int I> void f(A<I>, A<I+11>); // Ill-formed, no diagnostic required template <int I> void f(A<I>, A<I+10>); template <int I> void f(A<I>, A<I+1+2+3+4>);
-1- If a function template is overloaded, the use of a function template specialization might be ambiguous because template argument deduction (temp.deduct) may associate the function template specialization with more than one function template declaration. Partial ordering of overloaded function template declarations is used in the following contexts to select the function template to which a function template specialization refers:
-2- Given two overloaded function templates, whether one is more specialized than another can be determined by transforming each template in turn and using argument deduction (temp.deduct) to compare it to the other.
-3- The transformation used is:
-4- Using the transformed function parameter list, perform argument deduction against the other function template. The transformed template is at least as specialized as the other if, and only if, the deduction succeeds and the deduced parameter types are an exact match (so the deduction does not rely on implicit conversions).
-5- A template is more specialized than another if, and only if, it is at least as specialized as the other template and that template is not at least as specialized as the first. [Example:
template<class T> struct A { A(); }; template<class T> void f(T); template<class T> void f(T*); template<class T> void f(const T*); template<class T> void g(T); template<class T> void g(T&); template<class T> void h(const T&); template<class T> void h(A<T>&);
void m() { const int *p; f(p); //f(const T*) is more specialized than f(T) or f(T*) float x; g(x); // Ambiguous: g(T) or g(T&) A<int> z; h(z); // overload resolution selects h(A<T>&) const A<int> z2; h(z2); // h(const T&) is called because h(A<T>&) is not callable }
-6- The presence of unused ellipsis and default arguments has no effect on the partial ordering of function templates. [Example:
template<class T> void f(T); //#1 template<class T> void f(T*, int=1); // #2 template<class T> void g(T); // #3 template<class T> void g(T*, ...); // #4
int main() { int* ip; f(ip); //calls #2 g(ip); // calls #4 }
-1- Three kinds of names can be used within a template definition:
-2- A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename. [Example:
//no B declared here class X; template<class T> class Y { class Z; // forward declaration of member class void f() { X* a1; // declare pointer to X T* a2; // declare pointer to T Y* a3; // declare pointer to Y<T> Z* a4; // declare pointer to Z typedef typename T::A TA; TA* a5; // declare pointer to T's A typename T::A* a6; // declare pointer to T's A T::A* a7; // T::A is not a type name: // multiply T::A by a7; ill-formed, // no visible declaration of a7 B* a8; // B is not a type name: // multiply B by a8; ill-formed, // no visible declarations of B and a8 } };
-3- A qualified-name that refers to a type and that depends on a template-parameter (temp.dep) shall be prefixed by the keyword typename to indicate that the qualified-name denotes a type, forming an elaborated-type-specifier (dcl.type.elab).
elaborated-type-specifier: . . . typename ::opt nested-name-specifier identifier typename ::opt nested-name-specifier identifier < template-argument-list > . . .
-4- If a specialization of a template is instantiated for a set of template-arguments such that the qualified-name prefixed by typename does not denote a type, the specialization is ill-formed. The usual qualified name lookup (basic.lookup.qual) is used to find the qualified-name even in the presence of typename. [Example:
struct A { struct X { }; int X; }; template<class T> void f(T t) { typename T::X x; //ill-formed: finds the data member X // not the member type X }
-5- The keyword typename shall only be used in template declarations and definitions, including in the return type of a function template or member function template, in the return type for the definition of a member function of a class template or of a class nested within a class template, and in the type-specifier for the definition of a static member of a class template or of a class nested within a class template. The keyword typename shall only be applied to qualified names, but those names need not be dependent. The keyword typename is not permitted in a base-specifier or in a mem-initializer; in these contexts a qualified-name that depends on a template-parameter (temp.dep) is implicitly assumed to be a type name.
-6- Within the definition of a class template or within the definition of a member of a class template, the keyword typename is not required when referring to the unqualified name of a previously declared member of the class template that declares a type. The keyword typename shall always be specified when the member is referred to using a qualified name, even if the qualifier is simply the class template name. [Example:
The keyword typename is required whether the qualified name is A or A<T> because A or A<T> are synonyms within a class template with the parameter list <T>. ]template<class T> struct A { typedef int B; A::B b; //ill-formed: typename required before A::B void f(A<T>::B); // ill-formed: typename required before A<T>::B typename A::B g(); // OK };
-7- Knowing which names are type names allows the syntax of every template definition to be checked. No diagnostic shall be issued for a template definition for which a valid specialization can be generated. If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required. [Note: if a template is instantiated, errors will be diagnosed according to the other rules in this Standard. Exactly when these errors are diagnosed is a quality of implementation issue. ] [Example:
int j; template<class T> class X { //... void f(T t, int i, char* p) { t = i; // diagnosed if X::f is instantiated // and the assignment to t is an error p = i; // may be diagnosed even if X::f is // not instantiated p = j; // may be diagnosed even if X::f is // not instantiated } void g(T t) { +; // may be diagnosed even if X::g is // not instantiated } };
-8- When looking for the declaration of a name used in a template definition, the usual lookup rules (basic.lookup.unqual, basic.lookup.koenig) are used for nondependent names. The lookup of names dependent on the template parameters is postponed until the actual template argument is known (temp.dep). [Example:
in the example, i is the local variable i declared in printall, cnt is the member cnt declared in Set, and cout is the standard output stream declared in iostream. However, not every declaration can be found this way; the resolution of some names must be postponed until the actual template-arguments are known. For example, even though the name operator<< is known within the definition of printall() and a declaration of it can be found in <iostream>, the actual declaration of operator<< needed to print p[i] cannot be known until it is known what type T is (temp.dep). ]#include <iostream> using namespace std; template<class T> class Set { T* p; int cnt; public: Set(); Set<T>(const Set<T>&); void printall() { for (int i = 0; i<cnt; i++) cout << p[i] << '\n'; } //... };
-9- If a name does not depend on a template-parameter (as defined in temp.dep), a declaration (or set of declarations) for that name shall be in scope at the point where the name appears in the template definition; the name is bound to the declaration (or declarations) found at that point and this binding is not affected by declarations that are visible at the point of instantiation. [Example:
void f(char); template<class T> void g(T t) { f(1); //f(char) f(T(1)); // dependent f(t); // dependent dd++; // not dependent // error: declaration for dd not found }
void f(int); double dd; void h() { g(2); //will cause one call of f(char) followed // by two calls of f(int) g('a'); // will cause three calls of f(char) }
-10-
[Note:
for purposes of name lookup,
default arguments of function templates and default arguments of
member functions of class templates are considered definitions
(temp.decls).
--- end note]
14.6.1 - Locally declared names [temp.local]
-1- Within the scope of a class template, when the name of the template is neither qualified nor followed by <, it is equivalent to the name of the template followed by the template-parameters enclosed in <>. [Example: the constructor for Set can be referred to as Set() or Set<T>(). ] Other specializations (temp.expl.spec) of the class can be referred to by explicitly qualifying the template name with the appropriate template-arguments. [Example:
template<class T> class X { X* p; //meaning X<T> X<T>* p2; X<int>* p3; };
-2- Within the scope of a class template specialization or partial specialization, when the name of the template is neither qualified nor followed by <, it is equivalent to the name of the template followed by the template-arguments enclosed in <>. [Example:
template<class T> class Y; template<> class Y<int> { Y* p; //meaning Y<int> Y<char>* q; // meaning Y<char> };
-3- The scope of a template-parameter extends from its point of declaration until the end of its template. A template-parameter hides any entity with the same name in the enclosing scope. [Note: this implies that a template-parameter can be used in the declaration of subsequent template-parameters and their default arguments but cannot be used in preceding template-parameters or their default arguments. For example,
This also implies that a template-parameter can be used in the specification of base classes. For example,template<class T, T* p, class U = T> class X { /* ... */ }; template<class T> void f(T* p = new T);
The use of a template-parameter as a base class implies that a class used as a template-argument must be defined and not just declared when the class template is instantiated. ]template<class T> class X : public Array<T> { /* ... */ }; template<class T> class Y : public T { /* ... */ };
-4- A template-parameter shall not be redeclared within its scope (including nested scopes). A template-parameter shall not have the same name as the template name. [Example:
template<class T, int i> class Y { int T; //error: template-parameter redeclared void f() { char T; // error: template-parameter redeclared } }; template<class X> class X; // error: template-parameter redeclared
-5- In the definition of a member of a class template that appears outside of the class template definition, the name of a member of this template hides the name of a template-parameter. [Example:
template<class T> struct A { struct B { /* ... */ }; void f(); }; template<class B> void A<B>::f() { B b; //A's B, not the template parameter }
-6- In the definition of a member of a class template that appears outside of the namespace containing the class template definition, the name of a template-parameter hides the name of a member of this namespace. [Example:
namespace N { class C { }; template<class T> class B { void f(T); }; } template<class C> void N::B<C>::f(C) { C b; //C is the template parameter, not N::C }
-7- In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, for each base class which does not depend on a template-parameter (temp.dep), if the name of the base class or the name of a member of the base class is the same as the name of a template-parameter, the base class name or member name hides the template-parameter name (basic.scope.hiding). [Example:
struct A { struct B { /* ... */ }; int a; int Y; }; template<class B, class a> struct X : A { B b; //A's B a b; // error: A's a isn't a type name };
-1- Inside a template, some constructs have semantics which may differ from one instantiation to another. Such a construct depends on the template parameters. In particular, types and expressions may depend on the type and or value of template parameters (as determined by the template arguments) and this determines the context for name lookup for certain names. Expressions may be type-dependent (on the type of a template parameter) or value-dependent (on the value of a non-type template parameter). In an expression of the form:
where the postfix-expression is an identifier, the identifier denotes a dependent name if and only if any of the expressions in the expression-list is a type-dependent expression (temp.dep.expr). If an operand of an operator is a type-dependent expression, the operator also denotes a dependent name. Such names are unbound and are looked up at the point of the template instantiation (temp.point) in both the context of the template definition and the context of the point of instantiation.postfix-expression ( expression-listopt )
-2- [Example:
the base class name B<T>, the type name T::A, the names B<T>::i and pb->j explicitly depend on the template-parameter.template<class T> struct X : B<T> { typename T::A* pa; void f(B<T>* pb) { static int i = B<T>::i; pb->j++; } };
-3- In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, if a base class of this template depends on a template-parameter, the base class scope is not examined during name lookup until the class template is instantiated. [Example:
The type name A in the definition of X<T> binds to the typedef name defined in the global namespace scope, not to the typedef name defined in the base class B<T>. ]typedef double A; template<class T> B { typedef int A; }; template<class T> struct X : B<T> { A a; //a has type double };
-4- If a base class is a dependent type, a member of that class cannot hide a name declared within a template, or a name from the template's enclosing scopes. [Example:
struct A { struct B { /* ... */ }; int a; int Y; }; int a;
The members A::B, A::a, and A::Y of the template argument A do not affect the binding of names in Y<A>. ]template<class T> struct Y : T { struct B { /* ... */ }; B b; //The B defined in Y void f(int i) { a = i; } // ::a Y* p; // Y<T> }; Y<A> ya;
-1- A type is dependent if it is
-1- Except as described below, an expression is type-dependent if any subexpression is type-dependent.
-2- this is type-dependent if the class type of the enclosing member function is dependent (temp.dep.type).
-3- An id-expression is type-dependent if it contains:
simple-type-specifier ( expression-listopt ) ::opt new new-placementopt new-type-id new-initializeropt ::opt new new-placementopt ( type-id ) new-initializeropt dynamic_cast < type-id > ( expression ) static_cast < type-id > ( expression ) const_cast < type-id > ( expression ) reinterpret_cast < type-id > ( expression ) ( type-id ) cast-expression
-4- Expressions of the following forms are never type-dependent (because the type of the expression cannot be dependent):
literal postfix-expression . pseudo-destructor-name postfix-expression -> pseudo-destructor-name sizeof unary-expression sizeof ( type-id ) typeid ( expression ) typeid ( type-id ) ::opt delete cast-expression ::opt delete [ ] cast-expression throw assignment-expressionopt
-1- Except as described below, a constant expression is value-dependent if any subexpression is value-dependent.
-2- An identifier is value-dependent if it is:
sizeofunary-expression sizeof ( type-id )
-3- Expressions of the following form are value-dependent if either the type-id or simple-type-specifier is dependent or the expression or cast-expression is value-dependent:
simple-type-specifier ( expression-listopt ) static_cast < type-id > ( expression ) const_cast < type-id > ( expression ) reinterpret_cast < type-id > ( expression ) ( type-id ) cast-expression
-1- A type template-argument is dependent if the type it specifies is dependent.
-2- An integral non-type template-argument is dependent if the constant expression it specifies is value-dependent.
-3- A non-integral non-type template-argument is dependent if its type is dependent or it has either of the following forms
and contains a nested-name-specifier which specifies a class-name that names a dependent type.qualified-id & qualified-id
-4-
A template
template-argument
is dependent if it names a
template-parameter
or is a
qualified-id
with a
nested-name-specifier
which contains a
class-name
that names a dependent type.
14.6.3 - Non-dependent names [temp.nondep]
-1- Non-dependent names used in a template definition are found using the usual name lookup and bound at the point they are used. [Example:
void g(double); void h(); template<class T> class Z { public: void f() { g(1); //calls g(double) h++; // ill-formed: cannot increment function; // this could be diagnosed either here or // at the point of instantiation } }; void g(int); // not in scope at the point of the template // definition, not considered for the call g(1)
-1- In resolving dependent names, names from the following sources are considered:
-1- For a function template specialization, a member function template specialization, or a specialization for a member function or static data member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization and the context from which it is referenced depends on a template parameter, the point of instantiation of the specialization is the point of instantiation of the enclosing specialization. Otherwise, the point of instantiation for such a specialization immediately follows the namespace scope declaration or definition that refers to the specialization.
-2- If a function template or member function of a class template is called in a way which uses the definition of a default argument of that function template or member function, the point of instantiation of the default argument is the point of instantiation of the function template or member function specialization.
-3- For a class template specialization, a class member template specialization, or a specialization for a class member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization, if the context from which the specialization is referenced depends on a template parameter, and if the specialization is not instantiated previous to the instantiation of the enclosing template, the point of instantiation is immediately before the point of instantiation of the enclosing template. Otherwise, the point of instantiation for such a specialization immediately precedes the namespace scope declaration or definition that refers to the specialization.
-4- If a virtual function is implicitly instantiated, its point of instantiation is immediately following the point of instantiation of its enclosing class template specialization.
-5- An explicit instantiation directive is an instantiation point for the specialization or specializations specified by the explicit instantiation directive.
-6- The instantiation context of an expression that depends on the template arguments is the set of declarations with external linkage declared prior to the point of instantiation of the template specialization in the same translation unit.
-7-
A specialization for a function template, a member function template,
or of a member function or static data member of a class template may have
multiple points of instantiations within a translation unit.
A specialization for a class template has at most one point of instantiation
within a translation unit.
A specialization for any template may have points of instantiation in multiple
translation units.
If two different points of instantiation give a template specialization
different meanings according to the one definition rule (basic.def.odr),
the program is ill-formed, no diagnostic required.
14.6.4.2 - Candidate functions [temp.dep.candidate]
-1- For a function call that depends on a template parameter, if the function name is an unqualified-id but not a template-id, the candidate functions are found using the usual lookup rules (basic.lookup.unqual, basic.lookup.koenig) except that:
-1- Friend classes or functions can be declared within a class template. When a template is instantiated, the names of its friends are treated as if the specialization had been explicitly declared at its point of instantiation.
-2- As with non-template classes, the names of namespace-scope friend functions of a class template specialization are not visible during an ordinary lookup unless explicitly declared at namespace scope (class.friend). Such names may be found under the rules for associated classes (basic.lookup.koenig).*
[Footnote: Friend declarations do not introduce new names into any scope, either when the template is declared or when it is instantiated. --- end foonote][Example:
template<typename T> class number { number(int); //... friend number gcd(number& x, number& y) { /* ... */ } //... };
void g() { number<double> a(3), b(4); //... a = gcd(a,b); // finds gcd because number<double> is an // associated class, making gcd visible // in its namespace (global scope) b = gcd(3,4); // ill-formed; gcd is not visible }
-1- The act of instantiating a function, a class, a member of a class template or a member template is referred to as template instantiation.
-2- A function instantiated from a function template is called an instantiated function. A class instantiated from a class template is called an instantiated class. A member function, a member class, or a static data member of a class template instantiated from the member definition of the class template is called, respectively, an instantiated member function, member class or static data member. A member function instantiated from a member function template is called an instantiated member function. A member class instantiated from a member class template is called an instantiated member class.
-3- An explicit specialization may be declared for a function template, a class template, a member of a class template or a member template. An explicit specialization declaration is introduced by template<>. In an explicit specialization declaration for a class template, a member of a class template or a class member template, the name of the class that is explicitly specialized shall be a template-id. In the explicit specialization declaration for a function template or a member function template, the name of the function or member function explicitly specialized may be a template-id. [Example:
template<class T = int> struct A { static int x; }; template<class U> void g(U) { } template<> struct A<double> { }; //specialize for T == double template<> struct A<> { }; // specialize for T == int template<> void g(char) { } // specialize for U == char // U is deduced from the parameter type template<> void g<int>(int) { } // specialize for U == int template<> int A<char>::x = 0; // specialize for T == char template<class T = int> struct B { static int x; }; template<> int B<>::x = 1; // specialize for T == int
-4- An instantiated template specialization can be either implicitly instantiated (temp.inst) for a given argument list or be explicitly instantiated (temp.explicit). A specialization is a class, function, or class member that is either instantiated or explicitly specialized (temp.expl.spec).
-5- No program shall explicitly instantiate any template more than once, both explicitly instantiate and explicitly specialize a template, or specialize a template more than once for a given set of template-arguments. An implementation is not required to diagnose a violation of this rule.
-6- Each class template specialization instantiated from a template has its own copy of any static members. [Example:
X<int> has a static member s of type int and X<char*> has a static member s of type char*. ]template<class T> class X { static T s; //... }; template<class T> T X<T>::s = 0; X<int> aa; X<char*> bb;
-1- Unless a class template specialization has been explicitly instantiated (temp.explicit) or explicitly specialized (temp.expl.spec), the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type or when the completeness of the class type affects the semantics of the program. The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions or default arguments, of the class member functions, member classes, static data members and member templates; and it causes the implicit instantiation of the definitions of member anonymous unions. Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.
-2- Unless a function template specialization has been explicitly instantiated or explicitly specialized, the function template specialization is implicitly instantiated when the specialization is referenced in a context that requires a function definition to exist. Unless a call is to a function template explicit specialization or to a member function of an explicitly specialized class template, a default argument for a function template or a member function of a class template is implicitly instantiated when the function is called in a context that requires the value of the default argument.
-3- [Example:
template<class T> class Z { public: void f(); void g(); };
Nothing in this example requires class Z<double>, Z<int>::g(), or Z<char>::f() to be implicitly instantiated. ]void h() { Z<int> a; //instantiation of class Z<int> required Z<char>* p; // instantiation of class Z<char> not // required Z<double>* q; // instantiation of class Z<double> // not required a.f(); // instantiation of Z<int>::f() required p->g(); // instantiation of class Z<char> required, and // instantiation of Z<char>::g() required }
-4- A class template specialization is implicitly instantiated if the class type is used in a context that requires a completely-defined object type or if the completeness of the class type affects the semantics of the program; in particular, if an expression whose type is a class template specialization is involved in overload resolution, pointer conversion, pointer to member conversion, the class template specialization is implicitly instantiated (basic.def.odr); in addition, a class template specialization is implicitly instantiated if the operand of a delete expression is of class type or is of pointer to class type and the class type is a template specialization. [Example:
template<class T> class B { /* ... */ }; template<class T> class D : public B<T> { /* ... */ }; void f(void*); void f(B<int>*); void g(D<int>* p, D<char>* pp, D<double> ppp) { f(p); //instantiation of D<int> required: call f(B<int>*) B<char>* q = pp; // instantiation of D<char> required: // convert D<char>* to B<char>* delete ppp; // instantiation of D<double> required }
-5- If the overload resolution process can determine the correct function to call without instantiating a class template definition, it is unspecified whether that instantiation actually takes place. [Example:
template <class T> struct S { operator int(); }; void f(int); void f(S<int>&); void f(S<float>); void g(S<int>& sr) { f(sr); //instantiation of S<int> allowed but not required // instantiation of S<float> allowed but not required };
-6- If an implicit instantiation of a class template specialization is required and the template is declared but not defined, the program is ill-formed. [Example:
template<class T> class X; X<char> ch; //error: definition of X required
-7- The implicit instantiation of a class template does not cause any static data members of that class to be implicitly instantiated.
-8- If a function template or a member function template specialization is used in a way that involves overload resolution, a declaration of the specialization is implicitly instantiated (temp.over).
-9- An implementation shall not implicitly instantiate a function template, a member template, a non-virtual member function, a member class or a static data member of a class template that does not require instantiation. It is unspecified whether or not an implementation implicitly instantiates a virtual member function of a class template if the virtual member function would not otherwise be instantiated. The use of a template specialization in a default argument shall not cause the template to be implicitly instantiated except that a class template may be instantiated where its complete type is needed to determine the correctness of the default argument. The use of a default argument in a function call causes specializations in the default argument to be implicitly instantiated.
-10- Implicitly instantiated class and function template specializations are placed in the namespace where the template is defined. Implicitly instantiated specializations for members of a class template are placed in the namespace where the enclosing class template is defined. Implicitly instantiated member templates are placed in the namespace where the enclosing class or class template is defined. [Example:
namespace N { template<class T> class List { public: T* get(); //... }; }
template<class K, class V> class Map { N::List<V> lt; V get(K); //... };
a call of lt.get() from Map<char*,int>::get() would place List<int>::get() in the namespace N rather than in the global namespace. ]void g(Map<char*,int>& m) { int i = m.get("Nicholas"); //... }
-11- If a function template f is called in a way that requires a default argument expression to be used, the dependent names are looked up, the semantics constraints are checked, and the instantiation of any template used in the default argument expression is done as if the default argument expression had been an expression used in a function template specialization with the same scope, the same template parameters and the same access as that of the function template f used at that point. This analysis is called default argument instantiation. The instantiated default argument is then used as the argument of f.
-12- Each default argument is instantiated independently. [Example:
template<class T> void f(T x, T y = ydef(T()), T z = zdef(T())); class A { }; A zdef(A); void g(A a, A b, A c) { f(a, b, c); //no default argument instantiation f(a, b); // default argument z = zdef(T()) instantiated f(a); // ill-formed; ydef is not declared }
-13- [Note: temp.point defines the point of instantiation of a template specialization. ]
-14- There is an implementation-defined quantity that specifies the limit on the total depth of recursive instantiations, which could involve more than one template. The result of an infinite recursion in instantiation is undefined. [Example:
template<class T> class X { X<T>* p; //OK X<T*> a; // implicit generation of X<T> requires // the implicit instantiation of X<T*> which requires // the implicit instantiation of X<T**> which ... };
-1- A class, a function or member template specialization can be explicitly instantiated from its template. A member function, member class or static data member of a class template can be explicitly instantiated from the member definition associated with its class template.
-2- The syntax for explicit instantiation is:
If the explicit instantiation is for a class, a function or a member template specialization, the unqualified-id in the declaration shall be either a template-id or, where all template arguments can be deduced, a template-name. [Note: the declaration may declare a qualified-id, in which case the unqualified-id of the qualified-id must be a template-id. ] If the explicit instantiation is for a member function, a member class or a static data member of a class template specialization, the name of the class template specialization in the qualified-id for the member declarator shall be a template-id. [Example:explicit-instantiation: template declaration
template<class T> class Array { void mf(); }; template class Array<char>; template void Array<int>::mf(); template<class T> void sort(Array<T>& v) { /* ... */ } template void sort(Array<char>&); //argument is deduced here namespace N { template<class T> void f(T&) { } } template void N::f<int>(int&);
-3- A declaration of a function template shall be in scope at the point of the explicit instantiation of the function template. A definition of the class or class template containing a member function template shall be in scope at the point of the explicit instantiation of the member function template. A definition of a class template or class member template shall be in scope at the point of the explicit instantiation of the class template or class member template. A definition of a class template shall be in scope at the point of an explicit instantiation of a member function or a static data member of the class template. A definition of a member class of a class template shall be in scope at the point of an explicit instantiation of the member class. If the declaration of the explicit instantiation names an implicitly-declared special member function (clause special), the program is ill-formed.
-4- The definition of a non-exported function template, a non-exported member function template, or a non-exported member function or static data member of a class template shall be present in every translation unit in which it is explicitly instantiated.
-5- An explicit instantiation of a class or function template specialization is placed in the namespace in which the template is defined. An explicit instantiation for a member of a class template is placed in the namespace where the enclosing class template is defined. An explicit instantiation for a member template is placed in the namespace where the enclosing class or class template is defined. [Example:
namespace N { template<class T> class Y { void mf() { } }; } template class Y<int>; //error: class template Y not visible // in the global namespace using N::Y; template class Y<int>; // OK: explicit instantiation in namespace N template class N::Y<char*>; // OK: explicit instantiation in namespace N template void N::Y<double>::mf(); // OK: explicit instantiation // in namespace N
-6- A trailing template-argument can be left unspecified in an explicit instantiation of a function template specialization or of a member function template specialization provided it can be deduced from the type of a function parameter (temp.deduct). [Example:
template<class T> class Array { /* ... */ }; template<class T> void sort(Array<T>& v); //instantiate sort(Array<int>&) - template-argument deduced template void sort<>(Array<int>&);
-7- The explicit instantiation of a class template specialization implies the instantiation of all of its members not previously explicitly specialized in the translation unit containing the explicit instantiation.
-8- The usual access checking rules do not apply to names used to specify explicit instantiations. [Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects which would normally not be accessible and the template may be a member template or member function which would not normally be accessible. ]
-9- An explicit instantiation does not constitute a use of a default argument, so default argument instantiation is not done. [Example:
char* p = 0; template<class T> T g(T = &p); template int g<int>(int); //OK even though &p isn't an int.
-1- An explicit specialization of any of the following:
[Example:explicit-specialization: template < > declaration
template<class T> class stream; template<> class stream<char> { /* ... */ };
Given these declarations, stream<char> will be used as the definition of streams of chars; other streams will be handled by class template specializations instantiated from the class template. Similarly, sort<char*> will be used as the sort function for arguments of type Array<char*>; other Array types will be sorted by functions generated from the template. ]template<class T> class Array { /* ... */ }; template<class T> void sort(Array<T>& v) { /* ... */ } template<> void sort<char*>(Array<char*>&) ;
-2- An explicit specialization shall be declared in the namespace of which the template is a member, or, for member templates, in the namespace of which the enclosing class or enclosing class template is a member. An explicit specialization of a member function, member class or static data member of a class template shall be declared in the namespace of which the class template is a member. Such a declaration may also be a definition. If the declaration is not a definition, the specialization may be defined later in the namespace in which the explicit specialization was declared, or in a namespace that encloses the one in which the explicit specialization was declared.
-3- A declaration of a function template or class template being explicitly specialized shall be in scope at the point of declaration of an explicit specialization. [Note: a declaration, but not a definition of the template is required. ] The definition of a class or class template shall be in scope at the point of declaration of an explicit specialization for a member template of the class or class template. [Example:
template<> class X<int> { /* ... */ }; //error: X not a template template<class T> class X; template<> class X<char*> { /* ... */ }; // OK: X is a template
-4- A member function, a member class or a static data member of a class template may be explicitly specialized for a class specialization that is implicitly instantiated; in this case, the definition of the class template shall be in scope at the point of declaration of the explicit specialization for the member of the class template. If such an explicit specialization for the member of a class template names an implicitly-declared special member function (clause special), the program is ill-formed.
-5- A member of an explicitly specialized class is not implicitly instantiated from the member declaration of the class template; instead, the member of the class template specialization shall itself be explicitly defined. In this case, the definition of the class template explicit specialization shall be in scope at the point of declaration of the explicit specialization of the member. The definition of an explicitly specialized class is unrelated to the definition of a generated specialization. That is, its members need not have the same names, types, etc. as the members of the a generated specialization. Definitions of members of an explicitly specialized class are defined in the same manner as members of normal classes, and not using the explicit specialization syntax. [Example:
template<class T> struct A { void f(T) { /* ... */ } }; template<> struct A<int> { void f(int); };
void h() { A<int> a; a.f(16); //A<int>::f must be defined somewhere } // explicit specialization syntax not used for a member of // explicitly specialized class template specialization void A<int>::f() { /* ... */ }
-6- If a template, a member template or the member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required. If the program does not provide a definition for an explicit specialization and either the specialization is used in a way that would cause an implicit instantiation to take place or the member is a virtual member function, the program is ill-formed, no diagnostic required. An implicit instantiation is never generated for an explicit specialization that is declared but not defined. [Example:
template<class T> class Array { /* ... */ }; template<class T> void sort(Array<T>& v) { /* ... */ } void f(Array<String>& v) { sort(v); //use primary template // sort(Array<T>&), T is String } template<> void sort<String>(Array<String>& v); // error: specialization // after use of primary template template<> void sort<>(Array<char*>& v); // OK: sort<char*> not yet used
-7- The placement of explicit specialization declarations for function templates, class templates, member functions of class templates, static data members of class templates, member classes of class templates, member class templates of class templates, member function templates of class templates, member functions of member templates of class templates, member functions of member templates of non-template classes, member function templates of member classes of class templates, etc., and the placement of partial specialization declarations of class templates, member class templates of non-template classes, member class templates of class templates, etc., can affect whether a program is well-formed according to the relative positioning of the explicit specialization declarations and their points of instantiation in the translation unit as specified above and below. When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation.
-8- When a specialization for which an explicit specialization exists is used within the instantiation of an exported template, and the unspecialized template name is non-dependent in the exported template, a declaration of the explicit specialization shall be declared before the definition of the exported template, in the translation unit containing that definition. [Example:
//file #1 #include <vector> // Primary class template vector export template<class T> void f(t) { vector<T> vec; // should match the specialization /* ... */ } // file #2 #include <vector> class B { }; // Explicit specialization of vector for vector<B> template<class T> class vector<B> { /* ... */ } template<class T> void f(T); void g(B b) { f(b); // ill-formed: // f<B> should refer to vector<B>, but the // specialization was not declared with the // definition of f in file #1 }
-9- A template explicit specialization is in the scope of the namespace in which the template was defined. [Example:
namespace N { template<class T> class X { /* ... */ }; template<class T> class Y { /* ... */ }; template<> class X<int> { /* ... */ }; //OK: specialization // in same namespace template<> class Y<double>; // forward declare intent to // specialize for double } template<> class N::Y<double> { /* ... */ }; // OK: specialization // in same namespace
-10- A template-id that names a class template explicit specialization that has been declared but not defined can be used exactly like the names of other incompletely-defined classes (basic.types). [Example:
template<class T> class X; //X is a class template template<> class X<int>; X<int>* p; // OK: pointer to declared class X<int> X<int> x; // error: object of incomplete class X<int>
-11- A trailing template-argument can be left unspecified in the template-id naming an explicit function template specialization provided it can be deduced from the function argument type. [Example:
template<class T> class Array { /* ... */ }; template<class T> void sort(Array<T>& v); //explicit specialization for sort(Array<int>&) // with deduces template-argument of type int template<> void sort(Array<int>&);
-12- It is possible for a specialization with a given function signature to be instantiated from more than one function template. In such cases, explicit specification of the template arguments must be used to uniquely identify the function template specialization being specialized. [Example:
template <class T> void f(T); template <class T> void f(T*); template <> void f(int*); //Ambiguous template <> void f<int>(int*); // OK template <> void f(int); // OK
-13- A function with the same name as a template and a type that exactly matches that of a template specialization is not an explicit specialization (temp.fct).
-14- An explicit specialization of a function template is inline only if it is explicitly declared to be, and independently of whether its function template is. [Example:
template<class T> void f(T) { /* ... */ } template<class T> inline T g(T) { /* ... */ } template<> inline void f<>(int) { /* ... */ } //OK: inline template<> int g<>(int) { /* ... */ } // OK: not inline
-15- An explicit specialization of a static data member of a template is a definition if the declaration includes an initializer; otherwise, it is a declaration. [Note: there is no syntax for the definition of a static data member of a template that requires default initialization.
This is a declaration regardless of whether X can be default initialized (dcl.init). ]template<> X Q<int>::x;
-16- A member or a member template of a class template may be explicitly specialized for a given implicit instantiation of the class template, even if the member or member template is defined in the class template definition. An explicit specialization of a member or member template is specified using the template specialization syntax. [Example:
template<class T> struct A { void f(T); template<class X> void g(T,X); void h(T) { } }; //specialization template<> void A<int>::f(int); // out of class member template definition template<class T> template<class X> void A<T>::g(T,X) { }
//member template partial specialization template<> template<class X> void A<int>::g(int,X); // member template specialization template<> template<> void A<int>::g(int,char); // X deduced as char template<> template<> void A<int>::g<char>(int,char); // X specified as char // member specialization even if defined in class definition template<> void A<int>::h(int) { }
-17- A member or a member template may be nested within many enclosing class templates. If the declaration of an explicit specialization for such a member appears in namespace scope, the member declaration shall be preceded by a template<> for each enclosing class template that is explicitly specialized. [Example:
template<class T1> class A { template<class T2> class B { void mf(); }; }; template<> template<> A<int>::B<double> { }; template<> template<> void A<char>::B<char>::mf() { };
-18- In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well. In such explicit specialization declaration, the keyword template followed by a template-parameter-list shall be provided instead of the template<> preceding the explicit specialization declaration of the member. The types of the template-parameters in the template-parameter-list shall be the same as those specified in the primary template definition. [Example:
template<class T1> class A { template<class T2> class B { template<class T3> void mf1(T3); void mf2(); }; }; template<> template<class X> class A<int>::B { }; template<> template<> template<class T> void A<int>::B<double>::mf1(T t) { }; template<class Y> template<> void A<Y>::B<double>::mf2() { }; //ill-formed; B<double> is specialized but // its enclosing class template A is not
-19-
A specialization of a member function template or member class template of
a non-specialized class template is itself a template.
-1-
A function instantiated from a function template is called a function template
specialization; so is an explicit specialization of a function template.
Template arguments can either be explicitly specified when naming the function
template specialization or be deduced (temp.deduct) from the context, e.g.
from the function arguments in a call to the function template specialization.
-2-
Each function template specialization instantiated from a template
has its own copy of any static variable.
[Example:
-1-
Template arguments can be specified when referring to a function
template specialization by qualifying the function template
name with the list of
template-arguments
in the same way as
template-arguments
are specified in uses of a class template specialization.
[Example:
-2-
A template argument list may be specified when referring to a specialization
of a function template
-3-
Template arguments that are present shall be specified in the declaration
order of their corresponding
template-parameters.
The template argument list shall not specify more
template-arguments
than there are corresponding
template-parameters.
[Example:
-4-
Implicit conversions (clause conv) will be performed on a function argument
to convert it to the type of the corresponding function parameter if
the parameter type contains no
template-parameters
that participate in template argument deduction.
[Note:
template parameters do not participate in template argument deduction if
they are explicitly specified.
For example,
-5-
[Note:
because the explicit template argument list follows the function
template name, and because conversion member function templates and
constructor member function templates are called without using a
function name, there is no way to provide an explicit template
argument list for these function templates.
]
-6-
[Note:
For simple function names, argument dependent lookup (basic.lookup.koenig)
applies even when the function name is not visible within the scope of the call.
This is because the call still has the syntactic form of a function call
(basic.lookup.unqual).
But when a function template with explicit template arguments is used,
the call does not have the correct syntactic form unless there is a function
template with that name visible at the point of the call.
If no such name is visible,
the call is not syntactically well-formed and argument-dependent lookup
does not apply.
If some such name is visible,
argument dependent lookup applies and additional function templates
may be found in other namespaces.
[Example:
-1-
When a template function specialization is referenced, all of the
template arguments must have values.
The values can be either
explicitly specified or, in some cases, deduced from the use.
[Example:
-2-
When an explicit template argument list is specified, the template
arguments must be compatible with the template parameter list and must
result in a valid function type as described below; otherwise type
deduction fails. Specifically, the following steps are performed when
evaluating an explicitly specified template argument list with respect
to a given function template:
-3-
After this substitution is performed, the function parameter type
adjustments described in dcl.fct are performed.
[Example:
A parameter type of ``void ()(const int, int[5])'' becomes
``void(*)(int,int*)''.
]
[Note:
A top-level qualifier in a function parameter declaration does not affect
the function type but still affects the type of the function parameter
variable within the function.
-4-
The resulting substituted and adjusted function type is used as the
type of the function template for template argument deduction. When
all template arguments have been deduced, all uses of template
parameters in nondeduced contexts are replaced with the corresponding
deduced argument values. If the substitution results in an invalid
type, as described above, type deduction fails.
-5-
Except as described above, the use of an invalid value shall not cause
type deduction to fail.
[Example:
In the following example 1000 is converted to signed char and results
in an implementation-defined value as specified in (conv.integral).
In other words, both templates are considered even though 1000,
when converted to signed char, results in an implementation-defined
value.
-1-
Template argument deduction is done by comparing each function
template parameter type (call it
P)
with the type of the corresponding argument of the call (call it
A)
as described below.
-2-
If
P
is not a reference type:
-3-
In general, the deduction process attempts to find template argument
values that will make the deduced
A
identical to
A
(after
the type
A
is transformed as described above).
However, there are
three cases that allow a difference:
-1-
Template arguments can be deduced from the type specified when taking
the address of an overloaded function (over.over).
The function template's function type and the specified type
are used as the types of
P
and
A,
and the deduction is done as
described in temp.deduct.type.
-1-
Template argument deduction is done by comparing the return type of
the template conversion function (call it
P)
with the type that is
required as the result of the conversion (call it
A)
as described in temp.deduct.type.
-2-
If
A
is not a reference type:
-3-
In general, the deduction process attempts to find template argument
values that will make the deduced
A
identical to
A.
However, there are two cases that allow a difference:
-1-
Template arguments can be deduced in several different contexts, but
in each case a type that is specified in terms of template parameters
(call it
P)
is compared with an actual type (call it
A),
and an attempt is made to find template argument values (a type for a type
parameter, a value for a non-type parameter, or a template for a
template parameter) that will make
P,
after substitution of the deduced values (call it the deduced
A),
compatible with
A.
-2-
In some cases, the deduction is done using a single set of types
P
and
A,
in other cases, there will be a set of corresponding types
P
and
A.
Type deduction is done
independently for each
P/A
pair, and the deduced template
argument values are then combined.
If type deduction cannot be done
for any
P/A
pair, or if for any pair the deduction leads to more than
one possible set of deduced values, or if different pairs yield
different deduced values, or if any template argument remains neither
deduced nor explicitly specified, template argument deduction fails.
-3-
A given type
P
can be composed from a number of other
types, templates, and non-type values:
-4-
The nondeduced contexts are:
-5-
[Example:
Here is an example in which different parameter/argument pairs produce
inconsistent template argument deductions:
-6-
Here is an example where two template arguments are deduced from a
single function parameter/argument pair.
This can lead to conflicts
that cause type deduction to fail:
-7-
Here is an example where a qualification conversion applies between the
argument type on the function call and the deduced template argument type:
-8-
Here is an example where the template argument is used to instantiate
a derived class type of the corresponding function parameter type:
-9-
A template type argument
T,
a template template argument
TT
or a template non-type argument
i
can be deduced if
P
and
A
have one of the following forms:
-10-
These forms can be used in the same way as
T
is for further composition of types.
[Example:
-11-
Template arguments cannot be deduced from function arguments involving
constructs other than the ones specified above.
-12-
A template type argument cannot be deduced from the type of a non-type
template-argument.
[Example:
-13-
[Note:
except for reference and pointer types, a major array bound is not part of a
function parameter type and cannot be deduced from an argument:
-14-
If, in the declaration of a function template with a non-type
template-parameter,
the non-type
template-parameter
is used in an expression in the function parameter-list,
the corresponding
template-argument
must always be explicitly specified or deduced elsewhere because type
deduction would otherwise always fail for such a
template-argument.
-15-
If, in the declaration of a function template with a non-type
template-parameter,
the non-type
template-parameter
is used in an expression in the function parameter-list and,
if the corresponding
template-argument
is deduced, the
template-argument
type shall match the type of the
template-parameter
exactly, except that a
template-argument
deduced from an array bound may be of any integral type.*
-16-
A
template-argument
can be deduced from a pointer to function or pointer to member function
argument if the set of overloaded functions does not contain function templates
and at most one of a set of overloaded functions provides a unique match.
[Example:
-17-
A template
type-parameter
cannot be deduced from the type of a function default argument.
[Example:
-18-
The
template-argument
corresponding to a template
template-parameter
is deduced from the type of the
template-argument
of a class template specialization used in the argument list of a function call.
[Example:
-1-
A function template can be overloaded either by (non-template) functions of its
name or by (other) function templates of the same name.
When a call to that name is written (explicitly, or implicitly using the
operator notation), template argument deduction (temp.deduct)
and checking of any explicit template arguments (temp.arg) are performed
for each function template to find the template argument values (if any) that
can be used with that function template to instantiate a function template
specialization that can be invoked with the call arguments.
For each function template, if the argument deduction and checking succeeds,
the
template-arguments
(deduced and/or explicit)
are used to instantiate a single function template specialization which is
added to the candidate functions set to be used in overload resolution.
If, for a given function template, argument deduction fails, no such function
is added to the set of candidate functions for that template.
The complete set of candidate functions includes all the function templates
instantiated in this way and all of the non-template overloaded functions of
the same name.
The function template specializations are treated like any other functions in
the remainder of overload resolution, except as explicitly noted
in over.match.best.*
-2-
[Example:
-3-
Adding the non-template function
-4-
Here is an example involving conversions on a function argument involved in
template-argument
deduction:
-5-
Here is an example involving conversions on a function argument not involved in
template-parameter
deduction:
-6-
Only the signature of a function template specialization is needed to enter the
specialization in a set of candidate functions.
Therefore only the function template declaration is needed to resolve a call
for which a template specialization is a candidate.
[Example:
14.8 - Function template specializations [temp.fct.spec]
Here
f<int>(int*)
has a static variable
s
of type
int
and
f<char*>(char**)
has a static variable
s
of type
char*.
]
template<class T> void f(T* p)
{
static T s;
//
...
};
void g(int a, char* b)
{
f(&a); // call f<int>(int*)
f(&b); // call f<char*>(char**)
}
14.8.1 - Explicit template argument specification [temp.arg.explicit]
and
template<class T> void sort(Array<T>& v);
void f(Array<dcomplex>& cv, Array<int>& ci)
{
sort<dcomplex>(cv); //
sort(Array<dcomplex>&)
sort<int>(ci); // sort(Array<int>&)
}
template<class U, class V> U convert(V v);
void g(double d)
{
int i = convert<int,double>(d); //
int convert(double)
char c = convert<char,double>(d); // char convert(double)
}
--- end example]
Trailing template arguments that can be deduced (temp.deduct) may be
omitted from the list of explicit
template-arguments.
If all of the template arguments can be deduced, they may all be omitted;
in this case, the empty template argument list
<>
itself may also be omitted.
[Example:
template<class X, class Y> X f(Y);
void g()
{
int i = f<int>(5.6); //
Y is deduced to be double
int j = f(5.6); // ill-formed: X cannot be deduced
}
--- end example]
[Note:
An empty template argument list can be used to indicate that a given
use refers to a specialization of a function template even when a
normal (i.e., nontemplate) function is visible that would otherwise be used.
For example:
template <class T> int f(T); //
#1
int f(int); // #2
int k = f(1); // uses #2
int l = f<>(1); // uses #1
--- end note]
template<class X, class Y, class Z> X f(Y,Z);
void g()
{
f<int,char*,double>("aa",3.0);
f<int,char*>("aa",3.0); //
Z is deduced to be double
f<int>("aa",3.0); // Y is deduced to be char*, and
// Z is deduced to be double
f("aa",3.0); // error: X cannot be deduced
}
--- end example]
template<class T> void f(T);
class Complex {
//
...
Complex(double);
};
void g()
{
f<Complex>(1); // OK, means f<Complex>(Complex(1))
}
--- end note]
namespace A {
struct B { };
template<int X> void f();
}
namespace C {
template<class T> void f(T t);
}
void g(A::B b) {
f<3>(b); //
ill-formed: not a function call
A::f<3>(b); // well-formed
C::f<3>(b); // ill-formed; argument dependent lookup
// only applies to unqualified names
using C::f;
f<3>(b); // well-formed because C::f is visible; then
// A::f is found by argument dependent lookup
}
--- end example]
--- end note]
14.8.2 - Template argument deduction [temp.deduct]
and
void f(Array<dcomplex>& cv, Array<int>& ci)
{
sort(cv); //
call sort(Array<dcomplex>&)
sort(ci); // call sort(Array<int>&)
}
void g(double d)
{
int i = convert<int>(d); //
call convert<int,double>(double)
int c = convert<char>(d); // call convert<char,double>(double)
}
--- end example]
]
template <class T> int f(T[5]);
int I = f<int>(0);
int j = f<void>(0); //
invalid array
]
template <class T> int f(typename T::B*);
int i = f<int>(0);
]
template <class T> int f(typename T::B*);
struct A {};
struct C { int B; };
int i = f<A>(0);
int j = f<C>(0);
]
template <class T> int f(int T::*);
int i = f<int>(0);
]
template <class T, T*> int f(int);
int i2 = f<int,1>(0); //
can't conv 1 to int*
--- end note]
[Example:
template <class T> void f(T t);
template <class X> void g(const X x);
template <class Z> void h(Z, Z*);
int main()
{
//
#1: function type is f(int), t is nonconst
f<int>(1);
// #2: function type is f(int), t is const
f<const int>(1);
// #3: function type is g(int), x is const
g<int>(1);
// #4: function type is g(int), x is const
g<const int>(1);
// #5: function type is h(int, const int*)
h<const int>(1,0);
}
--- end example]
[Note:
f<int>(1) and f<const int>(1) call distinct functions
even though both of the functions called have the same function type.
--- end note]
template <int> int f(int);
template <signed char> int f(int);
int i1 = f<1>(0); //
ambiguous
int i2 = f<1000>(0); // ambiguous
--- end example]
14.8.2.1 - Deducing template arguments from a function call [temp.deduct.call]
If
P
is a cv-qualified type, the top level cv-qualifiers of
P's
type are ignored for type deduction.
If
P
is a reference type, the type
referred to by
P
is used for type deduction.
These alternatives are considered only if type deduction would
otherwise fail.
If they yield more than one possible deduced
A,
the type deduction fails.
[Note:
if a
template-parameter
is not used in any of the function parameters of a function template,
or is used only in a non-deduced context, its corresponding
template-argument
cannot be deduced from a function call and the
template-argument
must be explicitly specified.
]
14.8.2.2 - Deducing template arguments taking the address of a function template [temp.deduct.funcaddr]
14.8.2.3 - Deducing conversion function template arguments [temp.deduct.conv]
If
A
is a cv-qualified type, the top level cv-qualifiers of
A's
type are ignored for type deduction.
If
A
is a
reference type, the type referred to by
A
is used for type
deduction.
These alternatives are considered only if type deduction would
otherwise fail.
If they yield more than one possible deduced
A,
the type deduction fails.
14.8.2.4 - Deducing template arguments from a type [temp.deduct.type]
In most cases, the types, templates, and non-type values that are used
to compose
P
participate in template argument deduction.
That is,
they may be used to determine the value of a template argument, and
the value so determined must be consistent with the values determined
elsewhere.
In certain contexts, however, the value does not
participate in type deduction, but instead uses the values of template
arguments that were either deduced elsewhere or explicitly specified.
If a template parameter is used only in nondeduced contexts and is not
explicitly specified, template argument deduction fails.
When a type name is specified in a way that includes a nondeduced
context, all of the types that comprise that type name are also
nondeduced.
However, a compound type can include both deduced and nondeduced types.
[Example:
If a type is specified as
A<T>::B<T2>,
both
T
and
T2
are nondeduced.
Likewise, if a type is specified as
A<I+J>::X<T>,
I,
J,
and
T
are nondeduced.
If a type is specified as
void
f(A<T>::B,
A<T>),
the
T
in
A<T>::B
is nondeduced but
the
T
in
A<T>
is deduced.
]
template<class T> void f(T x, T y) { /* ... */ }
struct A { /* ... */ };
struct B : A { /* ... */ };
int g(A a, B b)
{
f(a,b); //
error: T could be A or B
f(b,a); // error: T could be A or B
f(a,a); // OK: T is A
f(b,b); // OK: T is B
}
template <class T, class U> void f( T (*)( T, U, U ) );
int g1( int, float, float);
char g2( int, float, float);
int g3( int, char, float);
void r()
{
f(g1); //
OK: T is int and U is float
f(g2); // error: T could be char or int
f(g3); // error: U could be char or float
}
template<class T> void f(const T*) {}
int *p;
void s()
{
f(p); //
f(const int *)
}
template <class T> struct B { };
template <class T> struct D : public B<T> {};
struct D2 : public B<int> {};
template <class T> void f(B<T>&){}
void t()
{
D<int> d;
D2 d2;
f(d); //
calls f(B<int>&)
f(d2); // calls f(B<int>&)
}
--- end example]
where
(T)
represents argument lists where at least one argument type contains a
T,
and
()
represents argument lists where no parameter contains a
T.
Similarly,
<T>
represents template argument lists where at least one argument contains a
T,
<i>
represents template argument lists where at least one argument contains an
i
and
<>
represents template argument lists where no argument contains a
T
or an
i.
T
cv-list T
T*
T&
T[integer-constant]
template-name<T> (where template-name refers to a class template)
type(*)(T)
T(*)()
T(*)(T)
T type::*
type T::*
T T::*
T (type::*)()
type (T::*)()
type (type::*)(T)
type (T::*)(T)
T (type::*)(T)
T (T::*)()
T (T::*)(T)
type[i]
template-name<i> (where template-name refers to a class template)
TT<T>
TT<i>
TT<>
is of the form
X<int> (*)(char[6])
which is a variant of
template-name<T> (*)(type[i])
where type is
X<int>
and
T
is
char[6].
]
type (*)(T)
template<class T, T i> void f(double a[10][i]);
int v[10][20];
f(v); //
error: argument for template-parameter T cannot be deduced
--- end example]
template<int i> void f1(int a[10][i]);
template<int i> void f2(int a[i][20]);
template<int i> void f3(int (&a)[i][20]);
void g()
{
int v[10][20];
f1(v); //
OK: i deduced to be 20
f1<20>(v); // OK
f2(v); // error: cannot deduce template-argument i
f2<10>(v); // OK
f3(v); // OK: i deduced to be 10
}
template<int i> class A { /* ... */ };
template<short s> void g(A<s+1>);
void k() {
A<1> a;
g(a); //
error: deduction fails for expression s+1
g<0>(a); // OK
}
--- end note]
[Note:
template parameters do not participate in template argument deduction if
they are used only in nondeduced contexts.
For example,
template<int i, typename T>
T deduce(typename A<T>::X x, //
T is not deduced here
T t, // but T is deduced here
typename B<i>::Y y); // i is not deduced here
A<int> a;
B<77> b;
int x = deduce<77>(a.xm, 62, y.ym);
//
T is deduced to be int, a.xm must be convertible to
// A<int>::X
// i is explicitly specified to be 77, y.ym must be convertible
// to B<77>::Y
--- end note]
[Footnote:
Although the
template-argument
corresponding to a
template-parameter
of type
bool
may be deduced from an array bound, the resulting value will always be
true
because the array bound will be non-zero.
--- end foonote]
[Example:
template<int i> class A { /* ... */ };
template<short s> void f(A<s>);
void k1() {
A<1> a;
f(a); //
error: deduction fails for conversion from int to short
f<1>(a); // OK
}
template<const short cs> class B { };
template<short s> void h(B<s>);
void k2() {
B<1> b;
g(b); //
OK: cv-qualifiers are ignored on template parameter types
}
--- end example]
template<class T> void f(void(*)(T,int));
template<class T> void foo(T,int);
void g(int,int);
void g(char,int);
void h(int,int,int);
void h(char,int);
int m()
{
f(&g); //
error: ambiguous
f(&h); // OK: void h(char,int) is a unique match
f(&foo); // error: type deduction fails because foo is a template
}
--- end example]
template <class T> void f(T = 5, T = 7);
void g()
{
f(1); //
OK: call f<int>(1,7)
f(); // error: cannot deduce T
f<int>(); // OK: call f<int>(5,7)
}
--- end example]
template <template X<class T> > struct A { };
template <template X<class T> > void f(A<X>) { }
template<class T> struct B { };
A<B> ab;
f(ab); //
calls f(A<B>)
--- end example]
[Note:
a default
template-argument
cannot be specified in a function template declaration or definition;
therefore default
template-arguments
cannot be used to influence template argument deduction.
]
14.8.3 - Overload resolution [temp.over]
[Footnote:
The parameters of function template specializations contain no
template parameter types.
The set of conversions allowed on deduced arguments is limited, because the
argument deduction process produces function templates with parameters that
either match the call arguments exactly or differ only in ways that can be
bridged by the allowed limited conversions.
Non-deduced arguments allow the full range of conversions.
Note also that over.match.best specifies that a non-template function will
be given preference over a template specialization if the two functions
are otherwise equally good candidates for an overload match.
--- end foonote]
template<class T> T max(T a, T b) { return a>b?a:b; }
void f(int a, int b, char c, char d)
{
int m1 = max(a,b); //
max(int a, int b)
char m2 = max(c,d); // max(char a, char b)
int m3 = max(a,c); // error: cannot generate max(int,char)
}
to the example above would resolve the third call, by providing a function that
could be called for
max(a,c)
after using the standard conversion of
char
to
int
for
c.
int max(int,int);
template<class T> struct B { /* ... */ };
template<class T> struct D : public B<T> { /* ... */ };
template<class T> void f(B<T>&);
void g(B<int>& bi, D<int>& di)
{
f(bi); //
f(bi)
f(di); // f( (B<int>&)di )
}
template<class T> void f(T*,int); //
#1
template<class T> void f(T,char); // #2
void h(int* pi, int i, char c)
{
f(pi,i); //
#1: f<int>(pi,i)
f(pi,c); // #2: f<int*>(pi,c)
f(i,c); // #2: f<int>(i,c);
f(i,i); // #2: f<int>(i,char(i))
}
--- end example]
The call of
f
is well-formed even if the template
f
is only declared and not defined at the point of the call.
The program will be ill-formed unless a specialization for
f<const char*>,
either implicitly or explicitly generated,
is present in some translation unit.
]
template<class T> void f(T); //
declaration
void g()
{
f("Annemarie"); // call of f<const char*>
}