Type deduction using the auto
keyword works almost the same as Template Type Deduction. Below are a few examples:
auto x = 27; // (x is neither a pointer nor a reference), x's type is int
const auto cx = x; // (cx is neither a pointer nor a reference), cs's type is const int
const auto& rx = x; // (rx is a non-universal reference), rx's type is a reference to a const int
auto&& uref1 = x; // x is int and lvalue, so uref1's type is int&
auto&& uref2 = cx; // cx is const int and lvalue, so uref2's type is const int &
auto&& uref3 = 27; // 27 is an int and rvalue, so uref3's type is int&&
The differences are outlined below:
auto x1 = 27; // type is int, value is 27
auto x2(27); // type is int, value is 27
auto x3 = { 27 }; // type is std::initializer_list<int>, value is { 27 }
auto x4{ 27 }; // type is std::initializer_list<int>, value is { 27 }
// in some compilers type may be deduced as an int with a
// value of 27. See remarks for more information.
auto x5 = { 1, 2.0 } // error! can't deduce T for std::initializer_list<t>
As you can see if you use braced initializers, auto is forced into creating a variable of type std::initializer_list<T>
. If it can't deduce the of T
, the code is rejected.
When auto
is used as the return type of a function, it specifies that the function has a trailing return type.
auto f() -> int {
return 42;
}
C++14 allows, in addition to the usages of auto allowed in C++11, the following:
When used as the return type of a function without a trailing return type, specifies that the function's return type should be deduced from the return statements in the function's body, if any.
// f returns int:
auto f() { return 42; }
// g returns void:
auto g() { std::cout << "hello, world!\n"; }
When used in the parameter type of a lambda, defines the lambda to be a generic lambda.
auto triple = [](auto x) { return 3*x; };
const auto x = triple(42); // x is a const int with value 126
The special form decltype(auto)
deduces a type using the type deduction rules of decltype
rather than those of auto
.
int* p = new int(42);
auto x = *p; // x has type int
decltype(auto) y = *p; // y is a reference to *p
In C++03 and earlier, the auto
keyword had a completely different meaning as a storage class specifier that was inherited from C.