Working Draft, Standard for Programming Language C++ (N4713, 2017 year) - page 13

 

  Главная      Manuals     Working Draft, Standard for Programming Language C++ (N4713, 2017 year)

 

Search            copyright infringement  

 

 

 

 

 

 

 

 

 

 

 

Content      ..     11      12      13      14     ..

 

 

 

Working Draft, Standard for Programming Language C++ (N4713, 2017 year) - page 13

 

 

xp->y the type of the expression is usually the type of the member y of the class of x (or the class pointed to
by xp). However, if x or xp refers to a dependent type that is not the current instantiation, the type of y is
always dependent. If x or xp refers to a non-dependent type or refers to the current instantiation, the type of
y is the type of the class member access expression.
— end note ]
6
A braced-init-list is type-dependent if any element is type-dependent or is a pack expansion.
7
A fold-expression is type-dependent.
17.7.2.3
Value-dependent expressions
[temp.dep.constexpr]
1
Except as described below, an expression used in a context where a constant expression is required is
value-dependent if any subexpression is value-dependent.
2
An id-expression is value-dependent if:
(2.1)
it is type-dependent,
(2.2)
it is the name of a non-type template parameter,
(2.3)
it names a static data member that is a dependent member of the current instantiation and is not
initialized in a member-declarator,
(2.4)
it names a static member function that is a dependent member of the current instantiation, or
(2.5)
it is a constant with literal type and is initialized with an expression that is value-dependent.
Expressions of the following form are value-dependent if the unary-expression or expression is type-dependent
or the type-id is dependent:
sizeof unary-expression
sizeof ( type-id )
typeid ( expression )
typeid ( type-id )
alignof ( type-id )
noexcept ( expression )
[ Note: For the standard library macro offsetof, see 21.2. — end note ]
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
4
Expressions of the following form are value-dependent:
sizeof ... ( identifier )
fold-expression
5
An expression of the form &qualified-id where the qualified-id names a dependent member of the current
instantiation is value-dependent. An expression of the form &cast-expression is also value-dependent if
evaluating cast-expression as a core constant expression (8.6) succeeds and the result of the evaluation refers
to a templated entity that is an object with static or thread storage duration or a member function.
17.7.2.4
Dependent template arguments
[temp.dep.temp]
1
A type template-argument is dependent if the type it specifies is dependent.
2
A non-type template-argument is dependent if its type is dependent or the constant expression it specifies is
value-dependent.
3
Furthermore, a non-type template-argument is dependent if the corresponding non-type template-parameter
is of reference or pointer type and the template-argument designates or points to a member of the current
instantiation or a member of a dependent type.
4
A template template-argument is dependent if it names a template-parameter or is a qualified-id that refers
to a member of an unknown specialization.
§ 17.7.2.4
352
17.7.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)
— end example ]
17.7.4
Dependent name resolution
[temp.dep.res]
1
In resolving dependent names, names from the following sources are considered:
(1.1)
Declarations that are visible at the point of definition of the template.
(1.2)
Declarations from namespaces associated with the types of the function arguments both from the
instantiation context (17.7.4.1) and from the definition context.
17.7.4.1
Point of instantiation
[temp.point]
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 noexcept-specifier of a function template specialization or specialization of a member function of a
class template, if the noexcept-specifier is implicitly instantiated because it is needed by another template
specialization and the context that requires it depends on a template parameter, the point of instantiation
of the noexcept-specifier is the point of instantiation of the specialization that requires it. Otherwise, the
point of instantiation for such a noexcept-specifier immediately follows the namespace scope declaration or
definition that requires the noexcept-specifier.
4
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.
5
If a virtual function is implicitly instantiated, its point of instantiation is immediately following the point of
instantiation of its enclosing class template specialization.
6
An explicit instantiation definition is an instantiation point for the specialization or specializations specified
by the explicit instantiation.
7
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.
§ 17.7.4.1
353
8
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, and
in addition to the points of instantiation described above, for any such specialization that has a point
of instantiation within the translation unit, the end of the translation unit is also considered a point of
instantiation. 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 (6.2), the program is ill-formed, no diagnostic required.
17.7.4.2
Candidate functions
[temp.dep.candidate]
1
For a function call where the postfix-expression is a dependent name, the candidate functions are found using
the usual lookup rules (6.4.1, 6.4.2) except that:
(1.1)
For the part of the lookup using unqualified name lookup (6.4.1), only function declarations from the
template definition context are found.
(1.2)
For the part of the lookup using associated namespaces (6.4.2), only function declarations found in
either the template definition context or the template instantiation context are found.
If the call would be ill-formed or would find a better match had the lookup within the associated namespaces
considered all the function declarations with external linkage introduced in those namespaces in all translation
units, not just considering those declarations found in the template definition and template instantiation
contexts, then the program has undefined behavior.
17.7.5
Friend names declared within a class template
[temp.inject]
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 (14.3). Such names
may be found under the rules for associated classes (6.4.2).143 [ Example:
template<typename T> struct number {
number(int);
friend number gcd(number x, number y) { return 0; };
};
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
}
— end example ]
17.8
Template instantiation and specialization
[temp.spec]
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, a member enumeration,
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, member enumeration, 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 simple-template-id. In the explicit
143) Friend declarations do not introduce new names into any scope, either when the template is declared or when it is
instantiated.
§ 17.8
354
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
— end example ]
4
An instantiated template specialization can be either implicitly instantiated (17.8.1) for a given argument
list or be explicitly instantiated (17.8.2). A specialization is a class, function, or class member that is either
instantiated or explicitly specialized (17.8.3).
5
For a given template and a given set of template-arguments,
(5.1)
an explicit instantiation definition shall appear at most once in a program,
(5.2)
an explicit specialization shall be defined at most once in a program (according to 6.2), and
(5.3)
both an explicit instantiation and a declaration of an explicit specialization shall not appear in a
program unless the explicit instantiation follows a declaration of the explicit specialization.
An implementation is not required to diagnose a violation of this rule.
6
The usual access checking rules do not apply to names in a declaration of an explicit instantiation or explicit
specialization, with the exception of names appearing in a function body, default argument, base-clause,
member-specification, enumerator-list, or static data member or variable template initializer.
[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 that would normally not be
accessible.
— end note ]
7
Each class template specialization instantiated from a template has its own copy of any static members.
[ Example:
template<class T> class X {
static T s;
};
template<class T> T X<T>::s = 0;
X<int> aa;
X<char*> bb;
X<int> has a static member s of type int and X<char*> has a static member s of type char*.
— end
example ]
8
If a function declaration acquired its function type through a dependent type (17.7.2.1) without using the
syntactic form of a function declarator, 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
— end example ]
§ 17.8
355
17.8.1
Implicit instantiation
[temp.inst]
1
Unless a class template specialization has been explicitly instantiated (17.8.2) or explicitly specialized (17.8.3),
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. [ Note: In particular, if the semantics of an expression depend on the member or base class
lists of a class template specialization, the class template specialization is implicitly generated. For instance,
deleting a pointer to class type depends on whether or not the class declares a destructor, and a conversion
between pointers to class type depends on the inheritance relationship between the two classes involved.
— end note ] [ 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
}
— end example ] If a class template has been declared, but not defined, at the point of instantiation (17.7.4.1),
the instantiation yields an incomplete class type (6.7). [ Example:
template<class T> class X;
X<char> ch;
// error: incomplete type X<char>
— end example ] [ Note: Within a template declaration, a local class (12.4) or enumeration and the members of
a local class are never considered to be entities that can be separately instantiated (this includes their default
arguments, noexcept-specifier s, and non-static data member initializers, if any, but not their partial-concept-ids
or requires-clauses). As a result, the dependent names are looked up, the semantic constraints are checked,
and any templates used are instantiated as part of the instantiation of the entity within which the local class
or enumeration is declared.
— end note ]
2
The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations,
but not of the definitions, default arguments, or noexcept-specifier s of the class member functions, member
classes, scoped member enumerations, static data members, member templates, and friends; and it causes the
implicit instantiation of the definitions of unscoped member enumerations and member anonymous unions.
However, for the purpose of determining whether an instantiated redeclaration is valid according to 6.2
and 12.2, a declaration that corresponds to a definition in the template is considered to be a definition.
[ Example:
template<class T, class U>
struct Outer {
template<class X, class Y> struct Inner;
template<class Y> struct Inner<T, Y>;
// #1a
template<class Y> struct Inner<T, Y> { };
// #1b; OK: valid redeclaration of #1a
template<class Y> struct Inner<U, Y> { };
// #2
};
Outer<int, int> outer;
// error at #2
Outer<int, int>::Inner<int, Y> is redeclared at #1b. (It is not defined but noted as being associated
with a definition in Outer<T, U>.)
#2 is also a redeclaration of #1a. It is noted as associated with a
definition, so it is an invalid redeclaration of the same partial specialization.
template<typename T> struct Friendly {
template<typename U> friend int f(U) { return sizeof(T); }
};
Friendly<char> fc;
Friendly<float> ff;
// ill-formed: produces second definition of f(U)
— end example ]
3
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
§ 17.8.1
356
a context that requires the member definition to exist or if the existence of the definition of the member
affects the semantics of the program; 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.
4
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 or if the existence of the definition affects the semantics of the program.
A function whose declaration was instantiated from a friend function definition is implicitly instantiated when
it is referenced in a context that requires a function definition to exist or if the existence of the definition
affects the semantics of the program. 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.
[ Example:
5
template<class T> struct Z {
void f();
void g();
};
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
}
Nothing in this example requires class Z<double>, Z<int>::g(), or Z<char>::f() to be implicitly instan-
tiated.
— end example ]
6
Unless a variable template specialization has been explicitly instantiated or explicitly specialized, the variable
template specialization is implicitly instantiated when it is referenced in a context that requires a variable
definition to exist or if the existence of the definition affects the semantics of the program. A default template
argument for a variable template is implicitly instantiated when the variable template is referenced in a
context that requires the value of the default argument.
7
The existence of a definition of a variable or function is considered to affect the semantics of the program if
the variable or function is needed for constant evaluation by an expression (8.6), even if constant evaluation
of the expression is not required or if constant expression evaluation does not use the definition.
[ Example:
template<typename T> constexpr int f() { return T::value; }
template<bool B, typename T> void g(decltype(B ? f<T>() : 0));
template<bool B, typename T> void g(...);
template<bool B, typename T> void h(decltype(int{B ? f<T>() : 0}));
template<bool B, typename T> void h(...);
void x() {
g<false, int>(0); // OK, B ? f<T>() :
0 is not potentially constant evaluated
h<false, int>(0); // error, instantiates f<int> even though B evaluates to false and
// list-initialization of int from int cannot be narrowing
}
— end example ]
8
If the function selected by overload resolution (16.3) can be determined 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);
§ 17.8.1
357
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
};
— end example ]
9
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 (17.9.3).
10
An implementation shall not implicitly instantiate a function template, a variable template, a member
template, a non-virtual member function, a member class, a static data member of a class template, or
a substatement of a constexpr if statement (9.4.1), unless such instantiation is required.
[Note: The
instantiation of a generic lambda does not require instantiation of substatements of a constexpr if statement
within its compound-statement unless the call operator template is instantiated.
— end note ] 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.
11
Implicitly instantiated class, function, and variable 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 {
public:
N::List<V> lt;
V get(K);
};
void g(Map<const char*,int>& m) {
int i = m.get("Nicholas");
}
a call of lt.get() from Map<const char*,int>::get() would place List<int>::get() in the namespace
N rather than in the global namespace.
— end example ]
12
If a function template f is called in a way that requires a default argument 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 is done as if the default argument had been an initializer 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, except that the scope in which a closure type is declared (8.4.5.1) - and therefore its
associated namespaces - remain as determined from the context of the definition for the default argument.
This analysis is called default argument instantiation. The instantiated default argument is then used as the
argument of f.
13
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);
§ 17.8.1
358
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
}
— end example ]
14
The noexcept-specifier of a function template specialization is not instantiated along with the function
declaration; it is instantiated when needed (18.4). If such an noexcept-specifier is needed but has not yet been
instantiated, the dependent names are looked up, the semantics constraints are checked, and the instantiation
of any template used in the noexcept-specifier is done as if it were being done as part of instantiating the
declaration of the specialization at that point.
15
[ Note: 17.7.4.1 defines the point of instantiation of a template specialization.
— end note ]
16
There is an implementation-defined quantity that specifies the limit on the total depth of recursive instan-
tiations (Annex B), 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 . . .
};
— end example ]
17
The partial-concept-ids and requires-clause of a template specialization or member function are not instantiated
along with the specialization or function itself, even for a member function of a local class; substitution
into the atomic constraints formed from them is instead performed as specified in 17.4.2 and 17.4.1.2 when
determining whether the constraints are satisfied. [ Note: The satisfaction of constraints is determined during
name lookup or overload resolution (16.3).
— end note ] [ Example:
template<typename T> concept C = sizeof(T) > 2;
template<typename T> concept D = C<T> && sizeof(T) > 4;
template<typename T> struct S {
S() requires C<T> { }
// #1
S() requires D<T> { }
// #2
};
S<char> s1;
// error: no matching constructor
S<char[8]> s2;
// OK, calls #2
When S<char> is instantiated, both constructors are part of the specialization. Their constraints are not
satisfied, and they suppress the implicit declaration of a default constructor for S<char> (15.1), so there is
no viable constructor for s1.
— end example ] [ Example:
template<typename T> struct S1 {
template<typename U>
requires false
struct Inner1;
// ill-formed, no diagnostic required
};
template<typename T> struct S2 {
template<typename U>
requires (sizeof(T[-(int)sizeof(T)]) > 1)
struct Inner2;
// ill-formed, no diagnostic required
};
The class S1<T>::Inner1 is ill-formed, no diagnostic required, because it has no valid specializations. S2 is
ill-formed, no diagnostic required, since no substitution into the constraints of its Inner2 template would
result in a valid expression.
— end example ]
§ 17.8.1
359
17.8.2
Explicit instantiation
[temp.explicit]
1
A class, function, variable, 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. An explicit instantiation of a function template,
member function of a class template, or variable template shall not use the inline or constexpr specifiers.
2
The syntax for explicit instantiation is:
explicit-instantiation:
externopt template declaration
There are two forms of explicit instantiation: an explicit instantiation definition and an explicit instantiation
declaration. An explicit instantiation declaration begins with the extern keyword.
3
If the explicit instantiation is for a class or member class, the elaborated-type-specifier in the declaration shall
include a simple-template-id; otherwise, the declaration shall be a simple-declaration whose init-declarator-list
comprises a single init-declarator that does not have an initializer. If the explicit instantiation is for a
function or member function, the unqualified-id in the declarator shall be either a template-id or, where
all template arguments can be deduced, a template-name or operator-function-id. [Note: The declaration
may declare a qualified-id, in which case the unqualified-id of the qualified-id must be a template-id.
— end
note ] 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
name shall be a simple-template-id. If the explicit instantiation is for a variable template specialization, the
unqualified-id in the declarator shall be a simple-template-id. An explicit instantiation shall appear in an
enclosing namespace of its template. If the name declared in the explicit instantiation is an unqualified name,
the explicit instantiation shall appear in the namespace where its template is declared or, if that namespace
is inline (10.3.1), any namespace from its enclosing namespace set. [Note: Regarding qualified names in
declarators, see 11.3.
— end note ] [ Example:
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&);
— end example ]
4
A declaration of a function template, a variable template, a member function or static data member of a class
template, or a member function template of a class or class template shall precede an explicit instantiation of
that entity. A definition of a class template, a member class of a class template, or a member class template of
a class or class template shall precede an explicit instantiation of that entity unless the explicit instantiation
is preceded by an explicit specialization of the entity with the same template arguments. If the declaration of
the explicit instantiation names an implicitly-declared special member function (Clause 15), the program is
ill-formed.
5
The declaration in an explicit-instantiation and the declaration produced by the corresponding substitution into
the templated function, variable, or class are two declarations of the same entity. [ Note: These declarations
are required to have matching types as specified in 6.5, except as specified in 18.4. [ Example:
template<typename T> T var = {};
template float var<float>;
// OK, instantiated variable has type float
template int var<int[16]>[];
// OK, absence of major array bound is permitted
template int *var<int>;
// error: instantiated variable has type int
template<typename T> auto av = T();
template int av<int>;
// OK, variable with type int can be redeclared with type auto
template<typename T> auto f() {}
template void f<int>();
// error: function with deduced return type
// redeclared with non-deduced return type (10.1.7.4)
§ 17.8.2
360
— end example ]
— end note ] Despite its syntactic form, the declaration in an explicit-instantiation for
a variable is not itself a definition and does not conflict with the definition instantiated by an explicit
instantiation definition for that variable.
6
For a given set of template arguments, if an explicit instantiation of a template appears after a declaration of
an explicit specialization for that template, the explicit instantiation has no effect. Otherwise, for an explicit
instantiation definition the definition of a function template, a variable template, a member function template,
or a member function or static data member of a class template shall be present in every translation unit in
which it is explicitly instantiated.
7
An explicit instantiation of a class, function template, or variable 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>;
// error: explicit instantiation outside of the namespace of the template
template class N::Y<char*>;
// OK: explicit instantiation in namespace N
template void N::Y<double>::mf();
// OK: explicit instantiation in namespace N
— end example ]
8
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 (17.9.2). [ 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>&);
— end example ]
9
[ Note: An explicit instantiation of a constrained template shall satisfy that template’s associated constraints
(17.4.2). The satisfaction of constraints is determined when forming the template name of an explicit
instantiation in which all template arguments are specified (17.2), or, for explicit instantiations of function
templates, during template argument deduction (17.9.2.6) when one or more trailing template arguments are
left unspecified.
— end note ]
10
An explicit instantiation that names a class template specialization is also an explicit instantiation of the
same kind (declaration or definition) of each of its members (not including members inherited from base
classes and members that are templates) that has not been previously explicitly specialized in the translation
unit containing the explicit instantiation, provided that the associated constraints, if any, of that member are
satisfied by the template arguments of the explicit instantiation (17.4.2, 17.4.1), except as described below.
[Note: In addition, it will typically be an explicit instantiation of certain implementation-dependent data
about the class.
— end note ]
11
An explicit instantiation definition that names a class template specialization explicitly instantiates the class
template specialization and is an explicit instantiation definition of only those members that have been
defined at the point of instantiation.
12
Except for inline functions and variables, declarations with types deduced from their initializer or return
value (10.1.7.4), const variables of literal types, variables of reference types, and class template specializations,
explicit instantiation declarations have the effect of suppressing the implicit instantiation of the definition
of the entity to which they refer.
[Note: The intent is that an inline function that is the subject of an
explicit instantiation declaration will still be implicitly instantiated when odr-used (6.2) so that the body
can be considered for inlining, but that no out-of-line copy of the inline function would be generated in the
translation unit. — end note ]
§ 17.8.2
361
13
If an entity is the subject of both an explicit instantiation declaration and an explicit instantiation definition
in the same translation unit, the definition shall follow the declaration. An entity that is the subject of
an explicit instantiation declaration and that is also used in a way that would otherwise cause an implicit
instantiation (17.8.1) in the translation unit shall be the subject of an explicit instantiation definition
somewhere in the program; otherwise the program is ill-formed, no diagnostic required. [Note: This rule
does apply to inline functions even though an explicit instantiation declaration of such an entity has no other
normative effect. This is needed to ensure that if the address of an inline function is taken in a translation
unit in which the implementation chose to suppress the out-of-line body, another translation unit will supply
the body. — end note ] An explicit instantiation declaration shall not name a specialization of a template
with internal linkage.
14
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 x = &p) { return x; }
template int g<int>(int);
// OK even though &p isn’t an int.
— end example ]
17.8.3
Explicit specialization
[temp.expl.spec]
1
An explicit specialization of any of the following:
(1.1)
function template
(1.2)
class template
(1.3)
variable template
(1.4)
member function of a class template
(1.5)
static data member of a class template
(1.6)
member class of a class template
(1.7)
member enumeration of a class template
(1.8)
member class template of a class or class template
(1.9)
member function template of a class or class template
can be declared by a declaration introduced by template<>; that is:
explicit-specialization:
template < > declaration
[ Example:
template<class T> class stream;
template<> class stream<char> { /* ... */ };
template<class T> class Array { /* ... */ };
template<class T> void sort(Array<T>& v) { /* ... */ }
template<> void sort<char*>(Array<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.
— end example ]
2
An explicit specialization may be declared in any scope in which the corresponding primary template may be
defined (10.3.1.2, 12.2, 17.6.2).
3
A declaration of a function template, class template, or variable template being explicitly specialized shall
precede the declaration of the explicit specialization.
[Note: A declaration, but not a definition of the
template is required.
— end note ] The definition of a class or class template shall precede the 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;
§ 17.8.3
362
template<> class X<char*> { /* ... */ };
// OK: X is a template
— end example ]
4
A member function, a member function template, a member class, a member enumeration, a member class
template, a static data member, or a static data member template 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 precede 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
15), 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 if its
definition is required. In this case, the definition of the class template explicit specialization shall be in scope
at the point at which the member is defined. 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 a generated specialization. Members of an explicitly specialized class template are defined
in the same manner as members of normal classes, and not using the template<> syntax. The same is true
when defining a member of an explicitly specialized member class. However, template<> is used in defining a
member of an explicitly specialized member class template that is specialized as a class template. [ Example:
template<class T> struct A {
struct B { };
template<class U> struct C { };
};
template<> struct A<int> {
void f(int);
};
void h() {
A<int> a;
a.f(16);
// A<int>::f must be defined somewhere
}
// template<> not used for a member of an explicitly specialized class template
void A<int>::f(int) { /* ... */ }
template<> struct A<char>::B {
void f();
};
// template<> also not used when defining a member of an explicitly specialized member class
void A<char>::B::f() { /* ... */ }
template<> template<class U> struct A<char>::C {
void f();
};
// template<> is used when defining a member of an explicitly specialized member class template
// specialized as a class template
template<>
template<class U> void A<char>::C<U>::f() { /* ... */ }
template<> struct A<short>::B {
void f();
};
template<> void A<short>::B::f() { /* ... */ }
// error: template<> not permitted
template<> template<class U> struct A<short>::C {
void f();
};
template<class U> void A<short>::C<U>::f() { /* ... */ }
// error: template<> required
— end example ]
6
If a template, a member template or a 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
§ 17.8.3
363
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:
class String { };
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
template<class T> struct A {
enum E : T;
enum class S : T;
};
template<> enum A<int>::E : int { eint };
// OK
template<> enum class A<int>::S : int { sint };
// OK
template<class T> enum A<T>::E : T { eT };
template<class T> enum class A<T>::S : T { sT };
template<> enum A<char>::E : char { echar };
// ill-formed, A<char>::E was instantiated
// when A<char> was instantiated
template<> enum class A<char>::S : char { schar };
// OK
— end example ]
7
The placement of explicit specialization declarations for function templates, class templates, variable templates,
member functions of class templates, static data members of class templates, member classes of class templates,
member enumerations of class templates, member class templates of class templates, member function
templates of class templates, static data member templates of class templates, member functions of member
templates of class templates, member functions of member templates of non-template classes, static data
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, variable templates, member
class templates of non-template classes, static data member 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
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 enclosing namespace
template<> class N::Y<short> { /* ... */ };
// OK: specialization in enclosing namespace
— end example ]
9
A simple-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 (6.7). [ 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>
§ 17.8.3
364
— end example ]
10
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 deduced template-argument of type int
template<> void sort(Array<int>&);
— end example ]
11
[ Note: An explicit specialization of a constrained template shall satisfy that template’s associated constraints
(17.4.2). The satisfaction of constraints is determined when forming the template name of an explicit
specialization in which all template arguments are specified (17.2), or, for explicit specializations of function
templates, during template argument deduction (17.9.2.6) when one or more trailing template arguments are
left unspecified.
— end note ]
12
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 (17.6.6).
13
An explicit specialization of a function or variable template is inline only if it is declared with the inline
specifier or defined as deleted, and independently of whether its function or variable template is inline.
[ 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
— end example ]
14
An explicit specialization of a static data member of a template or an explicit specialization of a static
data member template is a definition if the declaration includes an initializer; otherwise, it is a declaration.
[Note: The definition of a static data member of a template that requires default-initialization must use a
braced-init-list:
template<> X Q<int>::x;
// declaration
template<> X Q<int>::x ();
// error: declares a function
template<> X Q<int>::x { };
// definition
— end note ]
15
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 syntax for
explicit specialization. [ Example:
template<class T> struct A {
void f(T);
template<class X1> void g1(T, X1);
template<class X2> void g2(T, X2);
void h(T) { }
};
// specialization
template<> void A<int>::f(int);
// out of class member template definition
template<class T> template<class X1> void A<T>::g1(T, X1) { }
// member template specialization
template<> template<class X1> void A<int>::g1(int, X1);
// member template specialization
template<> template<>
void A<int>::g1(int, char);
// X1 deduced as char
§ 17.8.3
365
template<> template<>
void A<int>::g2<char>(int, char);
// X2 specified as char
// member specialization even if defined in class definition
template<> void A<int>::h(int) { }
— end example ]
16
A member or a member template may be nested within many enclosing class templates. In an explicit
specialization for such a member, 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<> class A<int>::B<double>;
template<> template<> void A<char>::B<char>::mf();
— end example ]
17
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-parameter s 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 <class T> void mf1(T);
};
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
— end example ]
18
A specialization of a member function template, member class template, or static data member template of a
non-specialized class template is itself a template.
19
An explicit specialization declaration shall not be a friend declaration.
20
Default function arguments shall not be specified in a declaration or a definition for one of the following
explicit specializations:
(20.1)
the explicit specialization of a function template;
(20.2)
the explicit specialization of a member function template;
(20.3)
the explicit specialization of a member function of a class template where the class template specialization
to which the member function specialization belongs is implicitly instantiated. [ Note: Default function
arguments may be specified in the declaration or definition of a member function of a class template
specialization that is explicitly specialized.
— end note ]
17.9
Function template specializations
[temp.fct.spec]
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 be explicitly specified when naming the
§ 17.9
366
function template specialization, deduced from the context (e.g., deduced from the function arguments in a
call to the function template specialization, see 17.9.2), or obtained from default template arguments.
2
Each function template specialization instantiated from a template has its own copy of any static variable.
[ Example:
template<class T> void f(T* p) {
static T s;
};
void g(int a, char* b) {
f(&a);
// calls f<int>(int*)
f(&b);
// calls f<char*>(char**)
}
Here f<int>(int*) has a static variable s of type int and f<char*>(char**) has a static variable s of type
char*.
— end example ]
17.9.1
Explicit template argument specification
[temp.arg.explicit]
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:
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>&)
}
and
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 ]
2
A template argument list may be specified when referring to a specialization of a function template
(2.1)
when a function is called,
(2.2)
when the address of a function is taken, when a function initializes a reference to function, or when a
pointer to member function is formed,
(2.3)
in an explicit specialization,
(2.4)
in an explicit instantiation, or
(2.5)
in a friend declaration.
3
Trailing template arguments that can be deduced (17.9.2) or obtained from default template-arguments
may be omitted from the list of explicit template-arguments. A trailing template parameter pack (17.6.3)
not otherwise deduced will be deduced to an empty sequence of 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. In contexts where deduction is done and fails, or in contexts where deduction
is not done, if a template argument list is specified and it, along with any default template arguments,
identifies a single function template specialization, then the template-id is an lvalue for the function template
specialization. [ Example:
template<class X, class Y> X f(Y);
template<class X, class Y, class ... Z> X g(Y);
void h() {
int i = f<int>(5.6);
// Y is deduced to be double
int j = f(5.6);
// ill-formed: X cannot be deduced
f<void>(f<int, bool>);
// Y for outer f deduced to be int (*)(bool)
f<void>(f<int>);
// ill-formed: f<int> does not denote a single function template specialization
int k = g<int>(5.6);
// Y is deduced to be double, Z is deduced to an empty sequence
§ 17.9.1
367
f<void>(g<int, bool>);
// Y for outer f is deduced to be int (*)(bool),
// Z is deduced to an empty sequence
}
— end example ]
4
[ 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 non-template function (11.3.5) 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 ]
5
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-parameter s unless one of the template-parameter s is a template parameter pack.
[ Example:
template<class X, class Y, class Z> X f(Y,Z);
template<class ... Args> void f2();
void g() {
f<int,const char*,double>("aa",3.0);
f<int,const char*>("aa",3.0); // Z is deduced to be double
f<int>("aa",3.0);
// Y is deduced to be const char*, and Z is deduced to be double
f("aa",3.0);
// error: X cannot be deduced
f2<char, short, int, long>(); // OK
}
— end example ]
6
Implicit conversions (Clause 7) 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,
template<class T> void f(T);
class Complex {
Complex(double);
};
void g() {
f<Complex>(1);
// OK, means f<Complex>(Complex(1))
}
— end note ]
7
[ 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.
— end
note ]
8
Template argument deduction can extend the sequence of template arguments corresponding to a template
parameter pack, even when the sequence contains explicitly specified template arguments. [ Example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0);
// Types is deduced to the sequence int*, float*, int
}
— end example ]
17.9.2
Template argument deduction
[temp.deduct]
1
When a function template specialization is referenced, all of the template arguments shall have values.
The values can be explicitly specified or, in some cases, be deduced from the use or obtained from default
§ 17.9.2
368
template-arguments. [ Example:
void f(Array<dcomplex>& cv, Array<int>& ci) {
sort(cv);
// calls sort(Array<dcomplex>&)
sort(ci);
// calls sort(Array<int>&)
}
and
void g(double d) {
int i = convert<int>(d);
// calls convert<int,double>(double)
int c = convert<char>(d);
// calls convert<char,double>(double)
}
— end example ]
2
When an explicit template argument list is specified, if the template arguments are not compatible with the
template parameter list or do not result in a valid function type as described below, type deduction fails.
Specifically, the following steps are performed when evaluating an explicitly specified template argument list
with respect to a given function template:
(2.1)
If the specified template arguments do not match the template parameters in kind (i.e., type, non-type,
template), or if there are more arguments than there are parameters and no parameter is a template
parameter pack, or if there is not an argument for each non-pack parameter, type deduction fails.
(2.2)
If any non-type argument does not match the type of the corresponding non-type template parameter,
and is not convertible to the type of the corresponding non-type parameter as specified in 17.3.2, type
deduction fails.
(2.3)
The specified template argument values are substituted for the corresponding template parameters as
specified below.
3
After this substitution is performed, the function parameter type adjustments described in 11.3.5 are
performed. [ Example: A parameter type of “void (const int, int[5])” becomes “void(*)(int,int*)”.
— end example ] [ 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.
— 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 non const
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 ]
4
[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 ]
5
The resulting substituted and adjusted function type is used as the type of the function template for template
argument deduction. If a template argument has not been deduced and its corresponding template parameter
has a default argument, the template argument is determined by substituting the template arguments
determined for preceding template parameters into the default argument. If the substitution results in an
invalid type, as described above, type deduction fails. [ Example:
§ 17.9.2
369
template <class T, class U = double>
void f(T t = 0, U u = 0);
void g() {
f(1, ’c’);
// f<int,char>(1,’c’)
f(1);
// f<int,double>(1,0)
f();
// error: T cannot be deduced
f<int>();
// f<int,double>(0,0)
f<int,char>();
// f<int,char>(0,0)
}
— end example ]
When all template arguments have been deduced or obtained from default template arguments, all uses
of template parameters in the template parameter list of the template and the function type are replaced
with the corresponding deduced or default argument values. If the substitution results in an invalid type,
as described above, type deduction fails. If the function template has associated constraints (17.4.2), those
constraints are checked for satisfaction (17.4.1). If the constraints are not satisfied, type deduction fails.
6
At certain points in the template argument deduction process it is necessary to take a function type
that makes use of template parameters and replace those template parameters with the corresponding
template arguments. This is done at the beginning of template argument deduction when any explicitly
specified template arguments are substituted into the function type, and again at the end of template
argument deduction when any template arguments that were deduced or obtained from default arguments
are substituted.
7
The substitution occurs in all types and expressions that are used in the function type and in template
parameter declarations. The expressions include not only constant expressions such as those that appear in
array bounds or as nontype template arguments but also general expressions (i.e., non-constant expressions)
inside sizeof, decltype, and other contexts that allow non-constant expressions. The substitution proceeds
in lexical order and stops when a condition that causes deduction to fail is encountered. [ Note: The equivalent
substitution in exception specifications is done only when the noexcept-specifier is instantiated, at which
point a program is ill-formed if the substitution results in an invalid type or expression.
— end note ]
[ Example:
template <class T> struct A { using X = typename T::X; };
template <class T> typename T::X f(typename A<T>::X);
template <class T> void f(...) { }
template <class T> auto g(typename A<T>::X) -> typename T::X;
template <class T> void g(...) { }
void h() {
f<int>(0);
// OK, substituting return type causes deduction to fail
g<int>(0);
// error, substituting parameter type instantiates A<int>
}
— end example ]
8
If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is
one that would be ill-formed, with a diagnostic required, if written using the substituted arguments. [ Note:
If no diagnostic is required, the program is still ill-formed. Access checking is done as part of the substitution
process.
— end note ] Only invalid types and expressions in the immediate context of the function type
and its template parameter types can result in a deduction failure. [ Note: The substitution into types and
expressions can result in effects such as the instantiation of class template specializations and/or function
template specializations, the generation of implicitly-defined functions, etc. Such effects are not in the
“immediate context” and can result in the program being ill-formed.
— end note ]
9
A lambda-expression appearing in a function type or a template parameter is not considered part of the
immediate context for the purposes of template argument deduction. [ Note: The intent is to avoid requiring
implementations to deal with substitution failure involving arbitrary statements. [ Example:
template <class T>
auto f(T) -> decltype([]() { T::invalid; } ());
void f(...);
f(0);
// error: invalid expression not part of the immediate context
§ 17.9.2
370
template <class T, std::size_t = sizeof([]() { T::invalid; })>
void g(T);
void g(...);
g(0);
// error: invalid expression not part of the immediate context
template <class T>
auto h(T) -> decltype([x = T::invalid]() { });
void h(...);
h(0);
// error: invalid expression not part of the immediate context
template <class T>
auto i(T) -> decltype([]() -> typename T::invalid { });
void i(...);
i(0);
// error: invalid expression not part of the immediate context
template <class T>
auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t));
// #1
void j(...);
// #2
j(0);
// deduction fails on #1, calls #2
— end example ]
— end note ]
10
[ Example:
struct X { };
struct Y {
Y(X){}
};
template <class T> auto f(T t1, T t2) -> decltype(t1 + t2);
// #1
X f(Y, Y);
// #2
X x1, x2;
X x3 = f(x1, x2);
// deduction fails on #1 (cannot add X+X), calls #2
— end example ]
11
[ Note: Type deduction may fail for the following reasons:
(11.1)
Attempting to instantiate a pack expansion containing multiple parameter packs of differing lengths.
(11.2)
Attempting to create an array with an element type that is void, a function type, a reference type, or an
abstract class type, or attempting to create an array with a size that is zero or negative. [ Example:
template <class T> int f(T[5]);
int I = f<int>(0);
int j = f<void>(0);
// invalid array
— end example ]
(11.3)
Attempting to use a type that is not a class or enumeration type in a qualified name. [ Example:
template <class T> int f(typename T::B*);
int i = f<int>(0);
— end example ]
(11.4)
Attempting to use a type in a nested-name-specifier of a qualified-id when that type does not contain
the specified member, or
(11.4.1)
the specified member is not a type where a type is required, or
(11.4.2)
the specified member is not a template where a template is required, or
(11.4.3)
the specified member is not a non-type where a non-type is required.
[ Example:
template <int I> struct X { };
template <template <class T> class> struct Z { };
template <class T> void f(typename T::Y*){}
template <class T> void g(X<T::N>*){}
template <class T> void h(Z<T::template TT>*){}
§ 17.9.2
371
struct A {};
struct B { int Y; };
struct C {
typedef int N;
};
struct D {
typedef int TT;
};
int main() {
// Deduction fails in each of these cases:
f<A>(0);
// A does not contain a member Y
f<B>(0);
// The Y member of B is not a type
g<C>(0);
// The N member of C is not a non-type
h<D>(0);
// The TT member of D is not a template
}
— end example ]
(11.5)
Attempting to create a pointer to reference type.
(11.6)
Attempting to create a reference to void.
(11.7)
Attempting to create “pointer to member of T” when T is not a class type. [ Example:
template <class T> int f(int T::*);
int i = f<int>(0);
— end example ]
(11.8)
Attempting to give an invalid type to a non-type template parameter. [ Example:
template <class T, T> struct S {};
template <class T> int f(S<T, T()>*);
struct X {};
int i0 = f<X>(0);
— end example ]
(11.9)
Attempting to perform an invalid conversion in either a template argument expression, or an expression
used in the function declaration. [ Example:
template <class T, T*> int f(int);
int i2 = f<int,1>(0);
// can’t conv 1 to int*
— end example ]
(11.10)
Attempting to create a function type in which a parameter has a type of void, or in which the return
type is a function type or array type.
(11.11)
Attempting to create a function type in which a parameter type or the return type is an abstract class
type (13.4).
— end note ]
12
[ Example: In the following example, assuming a signed char cannot represent the value 1000, a narrowing
conversion (11.6.4) would be required to convert the template-argument of type int to signed char, therefore
substitution fails for the second template (17.3.2).
template <int> int f(int);
template <signed char> int f(int);
int i1 = f<1000>(0);
// OK
int i2 = f<1>(0);
// ambiguous; not narrowing
— end example ]
17.9.2.1
Deducing template arguments from a function call
[temp.deduct.call]
1
Template argument deduction is done by comparing each function template parameter type (call it P)
that contains template-parameters that participate in template argument deduction with the type of the
corresponding argument of the call (call it A) as described below. If removing references and cv-qualifiers
from P gives std::initializer_list<P> or P[N] for some P and N and the argument is a non-empty
initializer list (11.6.4), then deduction is performed instead for each element of the initializer list, taking P
§ 17.9.2.1
372
as a function template parameter type and the initializer element as its argument, and in the P[N] case, if N
is a non-type template parameter, N is deduced from the length of the initializer list. Otherwise, an initializer
list argument causes the parameter to be considered a non-deduced context (17.9.2.5). [ Example:
template<class T> void f(std::initializer_list<T>);
f({1,2,3});
// T deduced to int
f({1,"asdf"});
// error: T deduced to both int and const char*
template<class T> void g(T);
g({1,2,3});
// error: no argument deduced for T
template<class T, int N> void h(T const(&)[N]);
h({1,2,3});
// T deduced to int, N deduced to 3
template<class T> void j(T const(&)[3]);
j({42});
// T deduced to int, array bound not considered
struct Aggr { int i; int j; };
template<int N> void k(Aggr const(&)[N]);
k({1,2,3});
// error: deduction fails, no conversion from int to Aggr
k({{1},{2},{3}});
// OK, N deduced to 3
template<int M, int N> void m(int const(&)[M][N]);
m({{1,2},{3,4}});
// M and N both deduced to 2
template<class T, int N> void n(T const(&)[N], T);
n({{1},{2},{3}},Aggr());
// OK, T is Aggr, N is 3
— end example ] For a function parameter pack that occurs at the end of the parameter-declaration-list,
deduction is performed for each remaining argument of the call, taking the type P of the declarator-id of the
function parameter pack as the corresponding function template parameter type. Each deduction deduces
template arguments for subsequent positions in the template parameter packs expanded by the function
parameter pack. When a function parameter pack appears in a non-deduced context (17.9.2.5), the type of
that parameter pack is never deduced. [ Example:
template<class ... Types> void f(Types& ...);
template<class T1, class ... Types> void g(T1, Types ...);
template<class T1, class ... Types> void g1(Types ..., T1);
void h(int x, float& y) {
const int z = x;
f(x, y, z);
// Types is deduced to int, float, const int
g(x, y, z);
// T1 is deduced to int; Types is deduced to float, int
g1(x, y, z);
// error: Types is not deduced
g1<int, int, int>(x, y, z);
// OK, no deduction occurs
}
— end example ]
2
If P is not a reference type:
(2.1)
If A is an array type, the pointer type produced by the array-to-pointer standard conversion (7.2) is
used in place of A for type deduction; otherwise,
(2.2)
If A is a function type, the pointer type produced by the function-to-pointer standard conversion (7.3)
is used in place of A for type deduction; otherwise,
(2.3)
If A is a cv-qualified type, the top-level cv-qualifiers of A’s type are ignored for type deduction.
3
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. [ Example:
template<class T> int f(const T&);
int n1 = f(5);
// calls f<int>(const int&)
const int i = 0;
int n2 = f(i);
// calls f<int>(const int&)
template <class T> int g(volatile T&);
int n3 = g(i);
// calls g<const int>(const volatile int&)
§ 17.9.2.1
373
— end example ] A forwarding reference is an rvalue reference to a cv-unqualified template parameter that does
not represent a template parameter of a class template (during class template argument deduction (16.3.1.8)).
If P is a forwarding reference and the argument is an lvalue, the type “lvalue reference to A” is used in place
of A for type deduction. [ Example:
template <class T> int f(T&& heisenreference);
template <class T> int g(const T&&);
int i;
int n1 = f(i);
// calls f<int&>(int&)
int n2 = f(0);
// calls f<int>(int&&)
int n3 = g(i);
// error: would call g<int>(const int&&), which
// would bind an rvalue reference to an lvalue
template <class T> struct A {
template <class U>
A(T&&, U&&, int*);
// #1: T&& is not a forwarding reference.
// U&& is a forwarding reference.
A(T&&, int*);
// #2
};
template <class T> A(T&&, int*) -> A<T>;
// #3: T&& is a forwarding reference.
int *ip;
A a{i, 0, ip};
// error: cannot deduce from #1
A a0{0, 0, ip};
// uses #1 to deduce A<int> and #1 to initialize
A a2{i, ip};
// uses #3 to deduce A<int&> and #2 to initialize
— end example ]
4
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:
(4.1)
If the original P is a reference type, the deduced A (i.e., the type referred to by the reference) can be
more cv-qualified than the transformed A.
(4.2)
The transformed A can be another pointer or pointer-to-member type that can be converted to the
deduced A via a function pointer conversion (7.13) and/or qualification conversion (7.5).
(4.3)
If P is a class and P has the form simple-template-id, then the transformed A can be a derived class of
the deduced A. Likewise, if P is a pointer to a class of the form simple-template-id, the transformed A
can be a pointer to a derived class pointed to by the deduced A.
5
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.
— end note ]
6
When P is a function type, function pointer type, or pointer-to-member-function type:
(6.1)
If the argument is an overload set containing one or more function templates, the parameter is treated
as a non-deduced context.
(6.2)
If the argument is an overload set (not containing function templates), trial argument deduction is
attempted using each of the members of the set. If deduction succeeds for only one of the overload set
members, that member is used as the argument value for the deduction. If deduction succeeds for more
than one member of the overload set the parameter is treated as a non-deduced context.
7
[ Example:
// Only one function of an overload set matches the call so the function parameter is a deduced context.
template <class T> int f(T (*p)(T));
int g(int);
int g(char);
int i = f(g);
// calls f(int (*)(int))
— end example ]
8
[ Example:
§ 17.9.2.1
374
// Ambiguous deduction causes the second function parameter to be a non-deduced context.
template <class T> int f(T, T (*p)(T));
int g(int);
char g(char);
int i = f(1, g);
// calls f(int, int (*)(int))
— end example ]
9
[ Example:
// The overload set contains a template, causing the second function parameter to be a non-deduced context.
template <class T> int f(T, T (*p)(T));
char g(char);
template <class T> T g(T);
int i = f(1, g);
// calls f(int, int (*)(int))
— end example ]
10
If deduction succeeds for all parameters that contain template-parameters that participate in template
argument deduction, and all template arguments are explicitly specified, deduced, or obtained from default
template arguments, remaining parameters are then compared with the corresponding arguments. For each
remaining parameter P with a type that was non-dependent before substitution of any explicitly-specified
template arguments, if the corresponding argument A cannot be implicitly converted to P, deduction fails.
[ Note: Parameters with dependent types in which no template-parameter s participate in template argument
deduction, and parameters that became non-dependent due to substitution of explicitly-specified template
arguments, will be checked during overload resolution.
— end note ] [ Example:
template <class T> struct Z {
typedef typename T::x xx;
};
template <class T> typename Z<T>::xx f(void *, T);
// #1
template <class T> void f(int, T);
// #2
struct A {} a;
int main() {
f(1, a);
// OK, deduction fails for #1 because there is no conversion from int to void*
}
— end example ]
17.9.2.2
Deducing template arguments taking the address of a function template
[temp.deduct.funcaddr]
1
Template arguments can be deduced from the type specified when taking the address of an overloaded
function (16.4). 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 17.9.2.5.
2
A placeholder type (10.1.7.4) in the return type of a function template is a non-deduced context. If template
argument deduction succeeds for such a function, the return type is determined from instantiation of the
function body.
17.9.2.3
Deducing conversion function template arguments
[temp.deduct.conv]
1
Template argument deduction is done by comparing the return type of the conversion function template (call
it P) with the type that is required as the result of the conversion (call it A; see 11.6, 16.3.1.5, and 16.3.1.6
for the determination of that type) as described in 17.9.2.5.
2
If P is a reference type, the type referred to by P is used in place of P for type deduction and for any further
references to or transformations of P in the remainder of this subclause.
3
If A is not a reference type:
(3.1)
If P is an array type, the pointer type produced by the array-to-pointer standard conversion (7.2) is
used in place of P for type deduction; otherwise,
(3.2)
If P is a function type, the pointer type produced by the function-to-pointer standard conversion (7.3)
is used in place of P for type deduction; otherwise,
(3.3)
If P is a cv-qualified type, the top-level cv-qualifiers of P’s type are ignored for type deduction.
4
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.
§ 17.9.2.3
375
5
In general, the deduction process attempts to find template argument values that will make the deduced A
identical to A. However, there are four cases that allow a difference:
(5.1)
If the original A is a reference type, A can be more cv-qualified than the deduced A (i.e., the type referred
to by the reference)
(5.2)
If the original A is a function pointer type, A can be “pointer to function” even if the deduced A is
“pointer to noexcept function”.
(5.3)
If the original A is a pointer-to-member-function type, A can be “pointer to member of type function”
even if the deduced A is “pointer to member of type noexcept function”.
(5.4)
The deduced A can be another pointer or pointer-to-member type that can be converted to A via a
qualification conversion.
6
These alternatives are considered only if type deduction would otherwise fail. If they yield more than one
possible deduced A, the type deduction fails.
7
When the deduction process requires a qualification conversion for a pointer or pointer-to-member type as
described above, the following process is used to determine the deduced template argument values:
If A is a type
cv1,0 “pointer to . . .” cv1,n−1 “pointer to” cv1,n T1
and P is a type
cv2,0 “pointer to . . .” cv2,n−1 “pointer to” cv2,n T2,
then the cv-unqualified T1 and T2 are used as the types of A and P respectively for type deduction.
[ Example:
struct A {
template <class T> operator T***();
};
A a;
const int * const * const * p1 = a;
// T is deduced as int, not const int
— end example ]
17.9.2.4
Deducing template arguments during partial ordering
[temp.deduct.partial]
1
Template argument deduction is done by comparing certain types associated with the two function templates
being compared.
2
Two sets of types are used to determine the partial ordering. For each of the templates involved there is
the original function type and the transformed function type. [ Note: The creation of the transformed type
is described in 17.6.6.2.
— end note ] The deduction process uses the transformed type as the argument
template and the original type of the other template as the parameter template. This process is done twice
for each type involved in the partial ordering comparison: once using the transformed template-1 as the
argument template and template-2 as the parameter template and again using the transformed template-2 as
the argument template and template-1 as the parameter template.
3
The types used to determine the ordering depend on the context in which the partial ordering is done:
(3.1)
In the context of a function call, the types used are those function parameter types for which the
function call has arguments.144
(3.2)
In the context of a call to a conversion function, the return types of the conversion function templates
are used.
(3.3)
In other contexts (17.6.6.2) the function template’s function type is used.
4
Each type nominated above from the parameter template and the corresponding type from the argument
template are used as the types of P and A. If a particular P contains no template-parameter s that participate
in template argument deduction, that P is not used to determine the ordering.
5
Before the partial ordering is done, certain transformations are performed on the types used for partial
ordering:
(5.1)
If P is a reference type, P is replaced by the type referred to.
144) Default arguments are not considered to be arguments in this context; they only become arguments after a function has
been selected.
§ 17.9.2.4
376
(5.2)
If A is a reference type, A is replaced by the type referred to.
6
If both P and A were reference types (before being replaced with the type referred to above), determine which
of the two types (if any) is more cv-qualified than the other; otherwise the types are considered to be equally
cv-qualified for partial ordering purposes. The result of this determination will be used below.
7
Remove any top-level cv-qualifiers:
(7.1)
If P is a cv-qualified type, P is replaced by the cv-unqualified version of P.
(7.2)
If A is a cv-qualified type, A is replaced by the cv-unqualified version of A.
8
Using the resulting types P and A, the deduction is then done as described in 17.9.2.5. If P is a function
parameter pack, the type A of each remaining parameter type of the argument template is compared with the
type P of the declarator-id of the function parameter pack. Each comparison deduces template arguments for
subsequent positions in the template parameter packs expanded by the function parameter pack. Similarly,
if A was transformed from a function parameter pack, it is compared with each remaining parameter type
of the parameter template. If deduction succeeds for a given type, the type from the argument template is
considered to be at least as specialized as the type from the parameter template. [ Example:
template<class... Args>
void f(Args... args);
// #1
template<class T1, class... Args> void f(T1 a1, Args... args);
// #2
template<class T1, class T2>
void f(T1 a1, T2 a2);
// #3
f();
// calls #1
f(1, 2, 3);
// calls #2
f(1, 2);
// calls #3; non-variadic template #3 is more specialized
// than the variadic templates #1 and #2
— end example ]
9
If, for a given type, deduction succeeds in both directions (i.e., the types are identical after the transformations
above) and both P and A were reference types (before being replaced with the type referred to above):
(9.1)
if the type from the argument template was an lvalue reference and the type from the parameter
template was not, the parameter type is not considered to be at least as specialized as the argument
type; otherwise,
(9.2)
if the type from the argument template is more cv-qualified than the type from the parameter template
(as described above), the parameter type is not considered to be at least as specialized as the argument
type.
10
Function template F is at least as specialized as function template G if, for each pair of types used to determine
the ordering, the type from F is at least as specialized as the type from G. F is more specialized than G if F is
at least as specialized as G and G is not at least as specialized as F.
11
If, after considering the above, function template F is at least as specialized as function template G and
vice-versa, and if G has a trailing parameter pack for which F does not have a corresponding parameter, and
if F does not have a trailing parameter pack, then F is more specialized than G.
12
In most cases, deduction fails if not all template parameters have values, but for partial ordering purposes a
template parameter may remain without a value provided it is not used in the types being used for partial
ordering. [Note: A template parameter used in a non-deduced context is considered used.
— end note ]
[ Example:
template <class T> T f(int);
// #1
template <class T, class U> T f(U);
// #2
void g() {
f<int>(1);
// calls #1
}
— end example ]
13
[Note: Partial ordering of function templates containing template parameter packs is independent of the
number of deduced arguments for those template parameter packs.
— end note ] [ Example:
template<class ...> struct Tuple { };
template<class ... Types> void g(Tuple<Types ...>);
// #1
template<class T1, class ... Types> void g(Tuple<T1, Types ...>);
// #2
template<class T1, class ... Types> void g(Tuple<T1, Types& ...>);
// #3
§ 17.9.2.4
377
g(Tuple<>());
// calls #1
g(Tuple<int, float>());
// calls #2
g(Tuple<int, float&>());
// calls #3
g(Tuple<int>());
// calls #3
— end example ]
17.9.2.5
Deducing template arguments from a type
[temp.deduct.type]
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. The type of a type parameter is only deduced from an array bound if it is not
otherwise deduced.
3
A given type P can be composed from a number of other types, templates, and non-type values:
(3.1)
A function type includes the types of each of the function parameters and the return type.
(3.2)
A pointer-to-member type includes the type of the class object pointed to and the type of the member
pointed to.
(3.3)
A type that is a specialization of a class template (e.g., A<int>) includes the types, templates, and
non-type values referenced by the template argument list of the specialization.
(3.4)
An array type includes the array element type and the value of the array bound.
4
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 template
argument deduction fails if the value so determined is not 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 non-deduced contexts and is not explicitly specified, template argument deduction fails. [ Note: Under
17.9.2.1 and 17.9.2.4, if P contains no template-parameter s that appear in deduced contexts, no deduction is
done, so P and A need not have the same form.
— end note ]
5
The non-deduced contexts are:
(5.1)
The nested-name-specifier of a type that was specified using a qualified-id.
(5.2)
The expression of a decltype-specifier.
(5.3)
A non-type template argument or an array bound in which a subexpression references a template
parameter.
(5.4)
A template parameter used in the parameter type of a function parameter that has a default argument
that is being used in the call for which argument deduction is being done.
(5.5)
A function parameter for which argument deduction cannot be done because the associated function
argument is a function, or a set of overloaded functions (16.4), and one or more of the following apply:
(5.5.1)
more than one function matches the function parameter type (resulting in an ambiguous deduction),
or
(5.5.2)
no function matches the function parameter type, or
(5.5.3)
the set of functions supplied as an argument contains one or more function templates.
(5.6)
A function parameter for which the associated argument is an initializer list (11.6.4) but the parameter
does not have a type for which deduction from an initializer list is specified (17.9.2.1). [ Example:
template<class T> void g(T);
g({1,2,3});
// error: no argument deduced for T
— end example ]
§ 17.9.2.5
378
(5.7)
A function parameter pack that does not occur at the end of the parameter-declaration-list.
6
When a type name is specified in a way that includes a non-deduced context, all of the types that comprise
that type name are also non-deduced. However, a compound type can include both deduced and non-deduced
types. [ Example: If a type is specified as A<T>::B<T2>, both T and T2 are non-deduced. Likewise, if a type is
specified as A<I+J>::X<T>, I, J, and T are non-deduced. If a type is specified as void f(typename A<T>::B,
A<T>), the T in A<T>::B is non-deduced but the T in A<T> is deduced.
— end example ]
7
[Example: Here is an example in which different parameter/argument pairs produce inconsistent template
argument deductions:
template<class T> void f(T x, T y) { /* ... */ }
struct A { /* ... */ };
struct B : A { /* ... */ };
void 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
}
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:
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
}
Here is an example where a qualification conversion applies between the argument type on the function call
and the deduced template argument type:
template<class T> void f(const T*) { }
int* p;
void s() {
f(p);
// f(const int*)
}
Here is an example where the template argument is used to instantiate a derived class type of the corresponding
function parameter type:
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 ]
8
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:
T
cv T
T*
T&
T&&
T[integer-constant ]
§ 17.9.2.5
379
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<>
where (T) represents a parameter-type-list (11.3.5) where at least one parameter type contains a T, and ()
represents a parameter-type-list where no parameter type 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.
9
If P has a form that contains <T> or <i>, then each argument Pi of the respective template argument list
of P is compared with the corresponding argument Ai of the corresponding template argument list of A.
If the template argument list of P contains a pack expansion that is not the last template argument, the
entire template argument list is a non-deduced context. If Pi is a pack expansion, then the pattern of Pi
is compared with each remaining argument in the template argument list of A. Each comparison deduces
template arguments for subsequent positions in the template parameter packs expanded by Pi. During partial
ordering (17.9.2.4), if Ai was originally a pack expansion:
(9.1)
if P does not contain a template argument corresponding to Ai then Ai is ignored;
(9.2)
otherwise, if Pi is not a pack expansion, template argument deduction fails.
[ Example:
template<class T1, class... Z> class S;
// #1
template<class T1, class... Z> class S<T1, const Z&...> { };
// #2
template<class T1, class T2> class S<T1, const T2&> { };
// #3
S<int, const int&> s;
// both #2 and #3 match; #3 is more specialized
template<class T, class... U>
struct A { };
// #1
template<class T1, class T2, class... U> struct A<T1, T2*, U...> { }; // #2
template<class T1, class T2>
struct A<T1, T2> { };
// #3
template struct A<int, int*>; // selects #2
— end example ]
10
Similarly, if P has a form that contains (T), then each parameter type Pi of the respective parameter-type-
list (11.3.5) of P is compared with the corresponding parameter type Ai of the corresponding parameter-type-list
of A. If P and A are function types that originated from deduction when taking the address of a function
template (17.9.2.2) or when deducing template arguments from a function declaration (17.9.2.6) and Pi
and Ai are parameters of the top-level parameter-type-list of P and A, respectively, Pi is adjusted if it is a
forwarding reference (17.9.2.1) and Ai is an lvalue reference, in which case the type of Pi is changed to be the
template parameter type (i.e., T&& is changed to simply T). [ Note: As a result, when Pi is T&& and Ai is X&,
the adjusted Pi will be T, causing T to be deduced as X&.
— end note ] [ Example:
template <class T> void f(T&&);
template <> void f(int&) { }
// #1
template <> void f(int&&) { }
// #2
void g(int i) {
f(i);
// calls f<int&>(int&), i.e., #1
§ 17.9.2.5
380
f(0);
// calls f<int>(int&&), i.e., #2
}
— end example ]
If the parameter-declaration corresponding to Pi is a function parameter pack, then the type of its declarator-id
is compared with each remaining parameter type in the parameter-type-list of A. Each comparison deduces
template arguments for subsequent positions in the template parameter packs expanded by the function
parameter pack. During partial ordering (17.9.2.4), if Ai was originally a function parameter pack:
(10.1)
if P does not contain a function parameter type corresponding to Ai then Ai is ignored;
(10.2)
otherwise, if Pi is not a function parameter pack, template argument deduction fails.
[ Example:
template<class T, class... U> void f(T*, U...) { }
// #1
template<class T>
void f(T) { }
// #2
template void f(int*);
// selects #1
— end example ]
11
These forms can be used in the same way as T is for further composition of types. [ Example:
X<int> (*)(char[6])
is of the form
template-name <T> (*)(type [i])
which is a variant of
type
(*)(T)
where type is X<int> and T is char[6].
— end example ]
12
Template arguments cannot be deduced from function arguments involving constructs other than the ones
specified above.
13
When the value of the argument corresponding to a non-type template parameter P that is declared with a
dependent type is deduced from an expression, the template parameters in the type of P are deduced from
the type of the value. [ Example:
template<long n> struct A { };
template<typename T> struct C;
template<typename T, T n> struct C<A<n>> {
using Q = T;
};
using R = long;
using R = C<A<2>>::Q;
// OK; T was deduced to long from the
// template argument value in the type A<2>
— end example ] The type of N in the type T[N] is std::size_t. [ Example:
template<typename T> struct S;
template<typename T, T n> struct S<int[n]> {
using Q = T;
};
using V = decltype(sizeof 0);
using V = S<int[42]>::Q;
// OK; T was deduced to std::size_t from the type int[42]
— end example ]
14
[ Example:
template<class T, T i> void f(int (&a)[i]);
int v[10];
void g() {
f(v);
// OK: T is std::size_t
}
— end example ]
§ 17.9.2.5
381

 

 

 

 

 

 

 

Content      ..     11      12      13      14     ..