[temp.deduct.general]

13 Templates [temp]

13.10 Function template specializations [temp.fct.spec]

13.10.3 Template argument deduction [temp.deduct]

13.10.3.1 General [temp.deduct.general]

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 template-arguments.

[Example 1:

void f(Array<dcomplex>& cv, Array<int>& ci) { sort(cv); sort(ci); } and void g(double d) { int i = convert<int>(d); int c = convert<char>(d); }

— end example]

Otherwise, the specified template argument values are substituted for the corresponding template parameters as specified below.

After this substitution is performed, the function parameter type adjustments described in [dcl.fct] are performed.

[Example 2:

A parameter type of “void (const int, int[5])” becomes “void(*)(int,int*).

— end example]

[Note 1:

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 3: template <class T> void f(T t); template <class X> void g(const X x); template <class Z> void h(Z, Z*); int main() { f<int>(1); f<const int>(1); g<int>(1); g<const int>(1); h<const int>(1,0); } — end example]

[Note 2:

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]

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 4: template <class T, class U = double> void f(T t = 0, U u = 0); void g() { f(1, 'c'); f(1); f(); f<int>(); f<int,char>(); } — 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 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 constraints are not satisfied, type deduction fails.

In the context of a function call, if type deduction has not yet failed, then for those function parameters for which the function call has arguments, each function parameter with a type that was non-dependent before substitution of any explicitly-specified template arguments is checked against its corresponding argument; if the corresponding argument cannot be implicitly converted to the parameter type, type deduction fails.

[Note 3:

Overload resolution will check the other parameters, including parameters with dependent types in which no template parameters participate in template argument deduction and parameters that became non-dependent due to substitution of explicitly-specified template arguments.

— end note]

If type deduction has not yet failed, then all uses of template parameters in 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.

[Example 5: template <class T> struct Z { typedef typename T::x xx; }; template <class T> concept C = requires { typename T::A; }; template <C T> typename Z<T>::xx f(void *, T); template <class T> void f(int, T); struct A {} a; struct ZZ { template <class T, class = typename Z<T>::xx> operator T *(); operator int(); }; int main() { ZZ zz; f(1, a); f(zz, 42); } — end example]

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.

The substitution occurs in all types and expressions that are used in the deduction substitution loci.

The expressions include not only constant expressions such as those that appear in array bounds or as constant 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.

If substitution into different declarations of the same function template would cause template instantiations to occur in a different order or not at all, the program is ill-formed; no diagnostic required.

[Example 6: 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(...) { } template <class T> typename T::X h(typename A<T>::X); template <class T> auto h(typename A<T>::X) -> typename T::X; template <class T> void h(...) { } void x() { f<int>(0); g<int>(0); h<int>(0); } — end example]

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 in the same context using the substituted arguments.

[Note 5:

If no diagnostic is required, the program is still ill-formed.

Access checking is done as part of the substitution process.

— end note]

Invalid types and expressions can result in a deduction failure only in the immediate context of the deduction substitution loci.

[Note 6:

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]

When substituting into a lambda-expression, substitution into its body is not in the immediate context.

[Note 7:

The intent is to avoid requiring implementations to deal with substitution failure involving arbitrary statements.

[Example 7: template <class T> auto f(T) -> decltype([]() { T::invalid; } ()); void f(...); f(0); template <class T, std::size_t = sizeof([]() { T::invalid; })> void g(T); void g(...); g(0); template <class T> auto h(T) -> decltype([x = T::invalid]() { }); void h(...); h(0); template <class T> auto i(T) -> decltype([]() -> typename T::invalid { }); void i(...); i(0); template <class T> auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t)); void j(...); j(0); — end example]

— end note]

[Example 8: struct X { }; struct Y { Y(X) {} }; template <class T> auto f(T t1, T t2) -> decltype(t1 + t2); X f(Y, Y); X x1, x2; X x3 = f(x1, x2); — end example]

[Note 8:

Type deduction can fail for the following reasons:

  • Attempting to instantiate a pack expansion containing multiple packs of differing lengths.

  • Attempting to create an array with an element type that is void, a function type, or a reference type, or attempting to create an array with a size that is zero or negative.

    [Example 9: template <class T> int f(T[5]); int I = f<int>(0); int j = f<void>(0); — end example]

  • Attempting to use a type that is not a class or enumeration type in a qualified name.

    [Example 10: template <class T> int f(typename T::B*); int i = f<int>(0); — end example]

  • Attempting to use a type in a nested-name-specifier of a qualified-id when that type does not contain the specified member, or

    • the specified member is not a type where a type is required, or
    • the specified member is not a template where a template is required, or
    • the specified member is not a non-type, non-template where a non-type, non-template is required.

    [Example 11: 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::TT>*) {} struct A {}; struct B { int Y; }; struct C { typedef int N; }; struct D { typedef int TT; }; int main() { f<A>(0); f<B>(0); g<C>(0); h<D>(0); } — end example]

  • Attempting to create a pointer to reference type.

  • Attempting to create a reference to void.

  • Attempting to create “pointer to member of T” when T is not a class type.

    [Example 12: template <class T> int f(int T::*); int i = f<int>(0); — end example]

  • Attempting to give an invalid type to a constant template parameter.

    [Example 13: template <class T, T> struct S {}; template <class T> int f(S<T, T{}>*); class X { int m; }; int i0 = f<X>(0); — end example]

  • Attempting to perform an invalid conversion in either a template argument expression, or an expression used in the function declaration.

    [Example 14: template <class T, T*> int f(int); int i2 = f<int,1>(0); — end example]

  • 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.

  • Attempting to give to an explicit object parameter of a lambda's function call operator a type not permitted for such ([expr.prim.lambda.closure]).

— end note]

template <int> int f(int); template <signed char> int f(int); int i1 = f<1000>(0); int i2 = f<1>(0); — end example]