02理解auto型别推导:
首先我们需要明确的是auto型别推导与模板型别推导的运作原理几乎完全相同,如下所见:
auto x = 27; // x型别为int
const auto cx = x; // cx型别为const int
const auto& rx = x; // rx型别为const int&
auto&& uref1 = x; // x为int,且为左值,所以uref1类型为int&
auto&& uref2 = cx; // cx为const int,为左值,所以uref2类型为const int&
auto&& uref3 = 27; // 27为int,且为右值,所以uref3 类型为int&&
const char name[] = "this is test"; // name型别为const char[13]
auto arr1 = name; // arr1型别为const char*
auto& arr2 = name; // name型别为const char(&)[13]
void somefunc(int,double); // somefunc是一个函数,型别为 void(int,double)
auto func1 = somefunc; // func1类型为void(*)(int,double)
auto& func1 = somefunc; // func2类型为void(&)(int,double)
C++11为了支持统一初始化,增加了大括号初始化表达式:
auto x1 = 27; //x1型别为int
auto x2(27); //x2型别为int
auto x3 = {27}; //x3型别为std::initializer_list<int>,含有一个变量
auto x4{27}; //x4型别为int
auto x5 = {27,13,0.5}; //x5型别无法推导,编译报错,因为里面包含两种数据类型
在对大括号括起来的表达式进行推导时,auto会将其推导为一个std::initializer_list的类型,但是使用单个元素且不使用等号时却又能推导正确。
auto规定函数返回值:
在C++14中,auto可以作为函数返回值推导,但是注意,此时会视auto为模板型别推导;换句话说,想返回大括号序列不会识别为std::initializer_list,因此无法完成模板推导;
auto func()
{
return {1,2,3}; // 编译报错,无法完成{1, 2, 3}的型别推导
}
lambda表达式捕获auto:
同理,使用auto来指定C++14中的lambda表达式形参型别时,也不能使用大括号括起来的初始化表达式来做实参:
std::vector<int> v;
auto resetV = [&v](const auto& new_value) {v = new_value};
resetV({1,2,3}); // 错误,无法完成{1,2,3}型别推导
Comments NOTHING