auto
type deduction is usually the same as template type deduction, with an exception in the case of braced initializer. Also, in C++14, as a function return type or a lambda parameter, auto
implies template type deduction instead of auto
type deduction.
With only one curious exception, auto
type deduction is template type deduction. In the case of general function template form and its general function call:
|
|
compilers use expr
to deduce types for T
and ParamType
. Similarly, in the case where a variable is declared using auto
, auto
plays the role of T
, and the type specifier for the variable acts as ParamType
.
Therefore, there are also three cases based on the type specifier:
- Case 1: the type specifier is a pointer or reference, but not a universal reference
- Case 2: the type specifier is a universal reference
- Case 3: the type specifier is neither a pointer nor a reference
For example:
|
|
Exception: uniform initialization
C++98 provides two syntactic choices when we want to declare an int with an initial value:
|
|
By introducing uniform initialization, C++11 adds these two forms:
|
|
As EMCpp 5 explains, there are advantages to declare variables using auto
, so we may prefer:
|
|
However, after this modification, while the first two statements do declare a variable of type int
with value 27, the second two actually declare a variable of type std::initializer_list<int>
containing a single element with value 27.
In fact, when an auto-declared variable is initialized with a braced initializer, auto
will assume that the braced initilizer represents a std::initializer_list
, which itself is a template for some type T
, so there are actually two kinds of type deduction taking place:
auto
type deduction: the type is an instantiation ofstd::initializer_list
- template type deduction: the type
T
instd::initializer_list<T>
The only real difference between auto
and template type deduction is the assumption that a braced initializer represents a std::initializer_list
. This lead to some interesting results:
|
|
More exceptions in C++14
C++14 permits to use auto
as a function’s return type as well as in lambda parameter declarations. However, these uses of auto
employ tamplate type deduction, not auto
type deduction - so a braced initializer won’t imply the type of std::initializer_list
automatically, and following statement won’t compile:
|
|