1Template argument deduction is done by comparing each function template parameter type (call it `P`

)
with the type of the corresponding argument of the call (call it `A`

) as described below. If removing
references and cv-qualifiers from `P`

gives `std::initializer_list<`

for some
`P`′>`P`′ and the argument is an initializer list (8.5.4), then deduction is performed instead for each
element of the initializer list, taking `P`′ as a function template parameter type and the initializer element
as its argument. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context
(14.8.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
```

— *end example* ]

For a function parameter pack that occurs at the end of the *parameter-declaration-list*, the type
`A`

of each remaining argument of the call 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. For a function parameter pack that
does not occur at the end of the *parameter-declaration-list*, the type of the parameter pack is a non-deduced
context.

[ *Example:*

```
template<class ... Types> void f(Types& ...);
template<class T1, class ... Types> void g(T1, Types ...);
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
}
```

— *end example* ]

2If `P`

is not a reference type:

- If
`A`

is an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is used in place of`A`

for type deduction; otherwise, - If
`A`

is a function type, the pointer type produced by the function-to-pointer standard conversion (4.3) is used in place of`A`

for type deduction; otherwise, - If
`A`

is a cv-qualified type, the top level cv-qualifiers of`A`

’s type are ignored for type deduction.

3If `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. If `P`

is an rvalue reference to a cv-unqualified template parameter 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&&);
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
```

— *end example* ]

4In 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:

- 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`

. - The transformed
`A`

can be another pointer or pointer to member type that can be converted to the deduced`A`

via a qualification conversion (4.4). - 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`

.

[ *Note:* as specified in 14.8.1, implicit conversions will be performed on a function argument to convert it
to the type of the corresponding function parameter if the parameter contains no *template-parameter*s that
participate in template argument deduction. Such conversions are also allowed, in addition to the ones described in the
preceding list. — *end note* ]

5These 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* ]

6When `P`

is a function type, pointer to function type, or pointer to member function type:

- If the argument is an overload set containing one or more function templates, the parameter is treated as a non-deduced context.
- 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:*

```
// 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* ]