Item 2 Understand auto type deduction

引子

模板类型推导与auto类型推导是具有映射关系的。
auto扮演T的角色,而类型限定符扮演ParamType的角色。
与模板类型推导相比,auto仅有一种特殊情况。

template
void f(ParamType param)

auto x = 27; //类型限定符就是auto
const auto cx = x; //类型限定符是const auto
const auto& rx =  x;  //类型限定符是const auto&

正文

Case 1和Case 3:

auto x = 27;           //对应Case 3
const auto cx = x;  //对应Case 3
const auto& rx = x; //对应Case 1

Case 2也如预期一样:

auto&& uref1 = x; //x是int左值,所以uref1是int&
auto&& uref2 = cx;//cx是const int左值,所以uref2是const int&
auto&& uref3 = 27; //27是int右值,uref3是int&&

auto推导也包含数组和函数隐式转换为指针的情况(没有引用类型限定符的情况下):

const char name[] = "R. N. Briggs";
auto arr1 = name;    //arr1's type is const char*
auto& arr2 = name;  //arr2's type is const char(&)[13]

void someFunc(int, double);
auto func1 = someFunc; //fun1's type is void (*)(int, double)
auto& func2 = someFunc; //fun2's type is void (&)(int, double)

上述讨论是auto与模板参数推导相似的部分。下面来看例外的情况:

int x1 = 27;
int x2(27);
int x3 = {27};
int x4{27};

auto x1 = 27;
auto x2(27);
auto x3 = {27};
auto x4{27};

使用int显示声明变量类型的表达式,将x1/x2/x3/x4都初始化为一个int类型初值为27的变量;而使用auto声明的变量,x1/x2是int类型初始为27的对象,x3/x4是类型为initializer_list的列表,且包含一个为27的元素。
即,在使用{}进行变量初始化时,auto会使用特殊的类型推导规则,除非类型无法被推导(如{}内的变量具有不同类型):

auto x5 = {1, 2, 3.0}; //error

template
void f(T param);
f({11,23,9}); //error

template
void f(std::initializer_list initlist);
f({11,23,9}); //T deduced as int

总结

  • auto类型推导与模板类型推导规则一致,但是遇到{}会推到成initializer_list
  • 函数返回值或lambda表达式参数中的auto是模板类型推导,而不是auto类型推导

你可能感兴趣的:(Item 2 Understand auto type deduction)