Let we have the following code
auto x = { 11, 23, 9 };
template<typename T> // template with parameter
void f(T param);
f({ 11, 23, 9 }); // error! can't deduce type for T
Here in the following code auto
is deduced automatically while template is not deduced automatically.
How auto
type is deduced?
what is auto
type behind the scenes?
Template argument deduction is used when selecting user-defined conversion function template arguments. A is the type that is required as the result of the conversion. P is the return type of the conversion function template.
With auto type deduction enabled, you no longer need to specify a type while declaring a variable. Instead, the compiler deduces the type of an auto variable from the type of its initializer expression.
auto is a keyword in C++11 and later that is used for automatic type deduction. The decltype type specifier yields the type of a specified expression. Unlike auto that deduces types based on values being assigned to the variable, decltype deduces the type from an expression passed to it.
" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.
auto
type deduction is usually the same as template type deduction, but auto
type deduction assumes that a braced initializer represents a std::initializer_list
, and template type deduction doesn’t.
When an auto
–declared variable is initialized with a
braced initializer, the deduced type is an instantiation of std::initializer_list
.
But if the corresponding template is passed the same initializer, type deduction fails,
and the code is rejected:
auto x = { 11, 23, 9 }; // x's type is
//std::initializer_list<int>
template<typename T> // template with parameter
void f(T param); // template with parameter
However, if you specify in the template that param is a std::initializer_list<T>
for some unknown T, template type deduction will deduce what T is:
template<typename T>
void f(std::initializer_list<T> initList);
f({ 11, 23, 9 }); // T deduced as int, and initList's
// type is std::initializer_list<int>
Remember
- auto type deduction is usually the same as template type deduction, but auto type deduction assumes that a braced initializer represents a
std::initializer_list
, and template type deduction doesn’t.
Auto type deduction takes different rules for list-initialization. With copy-list-initialization, the template parameter P is considered as std::initializer_list<U>
.
(emphasis mine)
The parameter P is obtained as follows: in T, the declared type of the variable that includes auto, every occurrence of auto is replaced with an imaginary type template parameter U or, if the initialization is copy-list-initialization, with
std::initializer_list<U>
. The argument A is the initializer expression.
Then for auto x = { 11, 23, 9 };
, the type of x
would be std::initializer_list<int>
.
For direct-list-initialization, the rule is different as:
In direct-list-initialization (but not in copy-list-initalization), when deducing the meaning of the auto 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:
auto x1 = {3}; // x1 is std::initializer_list<int> auto x2{1, 2}; // error: not a single element auto x3{3}; // x3 is int // (before N3922 x2 and x3 were both std::initializer_list<int>)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With