cpp/language/template argument deduction

In order to instantiate a, every template argument must be known, but not every template argument has to be specified. When possible, the compiler will deduce the missing template arguments from the function arguments. This occurs when a function call is attempted, when an address of a function template is taken, and in some other contexts:

This mechanism makes it possible to use template operators, since there is no syntax to specify template arguments for an operator other than by re-writing it as a function call expression:

Template argument deduction takes place after the function template (which may involve ) and before  (which may involve ) and.

Deduction from a function call
Template argument deduction attempts to determine template arguments (types for type template parameters i, templates for template template parameters i, and values for non-type template parameters i), which can be substituted into each parameter to produce the type deduced, which is the same as the type of the argument , after adjustments listed below.

If there are multiple parameters, each / pair is deduced separately and the deduced template arguments are then combined. If deduction fails or is ambiguous for any / pair or if different pairs yield different deduced template arguments, or if any template argument remains neither deduced nor explicitly specified, compilation fails.

If is a function type, pointer to function type, or pointer to member function type and if  is a  not containing function templates, template argument deduction is attempted with each overload. If only one succeeds, that successful deduction is used. If none or more than one succeeds, the template parameter is non-deduced context (see below):

Before deduction begins, the following adjustments to and  are made: @1@ If is not a reference type,
 * @a@ if is an array type,  is replaced by the pointer type obtained from array-to-pointer conversion;
 * @b@ otherwise, if is a function type,  is replaced by the pointer type obtained from function-to-pointer conversion;
 * @c@ otherwise, if is a cv-qualified type, the top-level cv-qualifiers are ignored for deduction:

@2@ If is a cv-qualified type, the top-level cv-qualifiers are ignored for deduction. @3@ If is a reference type, the referenced type is used for deduction. @4@ If is an rvalue reference to a cv-unqualified template parameter (so-called ), and the corresponding function call argument is an lvalue, the type lvalue reference to  is used in place of  for deduction (Note: this is the basis for the action of std ):

After these transformations, the deduction processes as described below (cf. section Deduction from a type) and attempts to find such template arguments that would make the deduced (that is,  after adjustments listed above and the substitution of the deduced template parameters) identical to the transformed, that is  after the adjustments listed above.

If the usual deduction from and  fails, the following alternatives are additionally considered: @1@ If is a reference type, the deduced  (i.e., the type referred to by the reference) can be more cv-qualified than the transformed :

@2@ The transformed can be another pointer or pointer to member type that can be converted to the deduced  via a  :

@3@ If is a class and  has the form, then the transformed  can be a derived class of the deduced. Likewise, if is a pointer to a class of the form simple-template-id, the transformed  can be a pointer to a derived class pointed to by the deduced :

Non-deduced contexts
In the following cases, the types, templates, and non-type values that are used to compose do not participate in template argument deduction, but instead use the 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.

@1@ The (everything to the left of the scope resolution operator ) of a type that was specified using a :

@3@ A non-type template argument or an array bound in which a subexpression references a template parameter:

@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@ The parameter, whose is a function or a set of overloads such that more than one function matches  or no function matches  or the set of overloads includes one or more function templates:

@6@ The parameter, whose is a braced-init-list, but  is not std, a reference to one (possibly cv-qualified):

@9@ For of array type (but not reference to array or pointer to array), the major array bound:

In any case, if any part of a type name is non-deduced, the entire type name is non-deduced context. However, compound types can include both deduced and non-deduced type names. For example, in, is non-deduced because of rule #1 (nested name specifier), and  is non-deduced because it is part of the same type name, but in , the  in  is non-deduced (because of the same rule), while the  in  is deduced.

Deduction from a type
Given a function parameter that depends on one or more type template parameters i, template template parameters i, or non-type template parameters i, and the corresponding argument, deduction takes place if  has one of the following forms:







In the above forms,
 * or represents a type or  that either satisfies these rules recursively, is a non-deduced context in  or, or is the same non-dependent type in  and.
 * or represents either a class template or a template template parameter.
 * represents an expression that either is an, is value-dependent in or , or has the same constant value in  and.

If has one of the forms that include a template parameter list  or, then each element i of that template argument list is matched against the corresponding template argument i of its. If the last i is a pack expansion, then its pattern is compared against each remaining argument in the template argument list of. A trailing parameter pack that is not otherwise deduced, is deduced to an empty parameter pack.

If has one of the forms that include a function parameter list, then each parameter i from that list is compared with the corresponding argument i from 's function parameter list. If the last i is a pack expansion, then its declarator is compared with each remaining i in the parameter type list of.

Forms can be nested and processed recursively:
 * is an example of, where is ;


 * is an example of, where is  and  is , and
 * is an example of, where  is  and  is.

If a non-type template parameter of function template is used in the template parameter list of function parameter (which is also a template), and the corresponding template argument is deduced, the type of the deduced template argument (as specified in its enclosing template parameter list, meaning references are preserved) must match the type of the non-type template parameter exactly, except that cv-qualifiers are dropped, and except where the template argument is deduced from an array bound—in that case any integral type is allowed, even though it would always become :

Type template parameter cannot be deduced from the type of a function default argument:

Deduction of template template parameter can use the type used in the template specialization used in the function call:

Other contexts
Besides function calls and operator expressions, template argument deduction is used in the following situations:

{{rrev|since=c++11|

auto type deduction
Template argument deduction is used in of variables, when deducing the meaning of the  from the variable's initializer.

The parameter is obtained as follows: in, the declared type of the variable that includes , every occurrence of  is replaced with an imaginary type template parameter  or, if the initialization is copy-list-initialization, with. The argument is the initializer expression. After deduction of from  and  following the rules described above, the deduced  is substituted into  to get the actual variable type:

In direct-list-initialization (but not in copy-list-initialization), when deducing the meaning of the from a braced-init-list, the braced-init-list must contain only one element, and the type of auto will be the type of that element:

}}

{{rrev|since=c++14|

auto-returning functions
Template argument deduction is used in declarations of, when deducing the meaning of the specifier in the function's return type, from the return statement.

For auto-returning functions, the parameter is obtained as follows: in, the declared return type of the function that includes , every occurrence of  is replaced with an imaginary type template parameter. The argument is the expression of the  statement, and if the return statement has no operand,  is. After deduction of from  and  following the rules described above, the deduced  is substituted into  to get the actual return type:

If such function has multiple return statements, the deduction is performed for each return statement. All the resulting types must be the same and become the actual return type.

If such function has no return statement, is  when deducing.

Note: the meaning of placeholder in variable and function declarations does not use template argument deduction. }}

Overload resolution
Template argument deduction is used during, when generating specializations from a candidate template function. and are the same as in a regular function call:

If deduction fails, or if deduction succeeds, but the specialization it produces would be invalid (for example, an overloaded operator whose parameters are neither class nor enumeration types), the specialization is not included in the overload set, similar to.

Address of an overload set
Template argument deduction is used when taking an, which includes function templates.

The function type of the function template is. The is the type of :

An additional rule is applied to the deduction in this case: when comparing function parameters i and i, if any i is an rvalue reference to cv-unqualified template parameter (a "forwarding reference") and the corresponding i is an lvalue reference, then i is adjusted to the template parameter type (T&& becomes T).

Partial ordering
Template argument deduction is used during.

Conversion function template
Template argument deduction is used when selecting template arguments.

is the type that is required as the result of the conversion. is the return type of the conversion function template. If is a reference type, then the referred type is used in place of  for the following parts of the section.

If is not a reference type: @a@ if the is an array type, then the pointer type obtained by array-to-pointer conversion is used in place of ; @b@ if the is a function type, then the function pointer type obtained by function-to-pointer conversion is used in place of ; @c@ if is cv-qualified, the top-level cv-qualifiers are ignored.

If is cv-qualified, the top-level cv-qualifiers are ignored. If is a reference type, the referred type is used by deduction.

If the usual deduction from and  (as described above) fails, the following alternatives are additionally considered: @a@ if is a reference type,  can be more cv-qualified than the deduced ; @b@ if is a pointer or pointer to member type, the deduced  is allowed to be any pointer that can be converted to  by qualification conversion:

See for other rules regarding conversion function templates.

Explicit instantiation
Template argument deduction is used in, , and those where the declarator-id happens to refer to a specialization of a function template (for example, ), if not all template arguments are explicitly specified or defaulted, template argument deduction is used to determine which template's specialization is referred to.

is the type of the function template that is being considered as a potential match, and is the function type from the declaration. If there are no matches or more than one match (after partial ordering), the function declaration is ill-formed:

An additional rule is applied to the deduction in this case: when comparing function parameters i and i, if any i is an rvalue reference to cv-unqualified template parameter (a "forwarding reference") and the corresponding i is an lvalue reference, then i is adjusted to the template parameter type (T&& becomes T).

Deallocation function template
Template argument deduction is used when determining if a deallocation function template specialization matches a given placement form of.

is the type of the function template that is being considered as a potential match, and is the function type of the deallocation function that would be the match for the placement operator new under consideration. If there is no match or more than one match (after overload resolution), the placement deallocation function is not called (memory leak may occur):

Alias templates
are not deduced :

Implicit conversions
Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for, which happens later.

However, if deduction succeeds for all parameters that participate in template argument deduction, and all template arguments that aren't deduced are explicitly specified or defaulted, then the remaining function parameters are compared with the corresponding function arguments. For each remaining parameter with a type that was non-dependent before substitution of any explicitly-specified template arguments, if the corresponding argument  cannot be implicitly converted to, deduction fails.

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 will be checked during overload resolution: