Item 2: Understand auto Type Deduction

Same as template type deduction, except for std::initializer_list.

Special type deduction rule for auto: When the initializer for an auto-declared variable is enclosed in braces, the deduced type is a std::initializer_list.

auto x1 = 27;    // x1: int
auto x2(27);     // x2: int
auto x3 = {27};  // x3: std::initializer<int>
auto x4{27};     // x4: std::initializer<int>

(By the way, under N3922 (not C++11 nor C++14), when using direct initialization syntax, (i.e., auto x4{27}), the type of x4 is int, not std::initializer_list.)

In other words, auto type deduction assumes that a brace initializer represents a std::initializer_list, but template type deduction doesn’t. (Scott Meyers doesn’t know the rationale behind this special rule, either.)

// This compiles due to the special rule for auto
auto x = {1, 2, 3};

// This doesn't compile
template<typename T> void f(T param);
f({1, 2, 3});  // Error! Can't deduce type for T

// This compiles
template<typename T> void f(std::initializer_list<T> initList);
f({1, 2, 3});

C++14: You may put auto in function’s return type and lambda’s parameter declaration. While C++ reuses the auto keyword, it is template type deduction rule that applies in these places, not auto type deduction rule. (This is so confusing…)

// C++14
auto foo() {
  return {1, 2, 3};  // Error! Can't deduce type for {1, 2, 3}
}

// C++14
auto foo = [&v](const auto& newValue) { v = newValue };
foo({1, 2, 3});  // Error! Can't deduce type for {1, 2, 3}
Creative Commons License
This blog by Che-Liang Chiou is licensed under a Creative Commons Attribution 4.0 International License.