|
想要查看内容赶紧注册登陆吧!
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
在Item1中介绍了C++98的模板类型推导,而C++11中引入的auto其类型推导规则和模板类型是如出一辙的。在Item1中提到的模板类型推导规则可以总结为如下形式:
- template<typename T>
- void f(`参数类型` param)
- f(var)
复制代码 根据参数类型和传入的var的类型的不同,推导的规则也相应不同,那么auto是如何和模板推导规则关联呢?
- auto x = 27 //对应Item1中的Case3,x的类型就是int
- int& z = x;
- const int y = 19;
- auto cx = x; //对应Item1中的Case3,cx的类型就是int,忽略了y的CV限制符和引用等
- const auto& rx = z; //对应Item1中的Case1,rx的类型是const引用类型,忽略z的引用
- auto&& rrx = 27 //对应Item1中的Case2,rrx的类型int&&
- 参数类型 param = var
复制代码 auto可以总结为上面这种形式。根据赋值操作右边的var类型,和变量名左边的参数类型结合起来进行推导。在Item1中还提到了两个额外的类型推导,一个是数组类型,另外一个是函数类型。对应到auto则如下:
- const char name[] = "test";
- auto arr1 = name; //arr1的类型是const char*类型
- auto& arr2 = name; //arr2的类型是const char(&)[5]
- void someFunc(int,doubel);
- auto func1 = someFunc; //void(*)(int,double)
- auto& func2 = someFunc; //void(&)(int,double)
复制代码 除了上面提到的推导规则外,auto还有一个和模板类型推导不一样的地方。这也是本节Item需要关注的。在C++11中引入了统一初始化列表,相对应的则是std::initializer_list<T>模板类型。
- auto x1 = {1,2,3}; //此时x1被推导为std::initializer_list<T>
复制代码 因为初始化列表是模板类型,因此所有的元素必须是同一类型,否则会初始化失败。对应到模板类型推导如下:
- auto x = {11,23,9}
- template<typename T>
- void f(T param);
- f(x); //编译错误,无法进行推导。
复制代码 模板类型推导居然无法识别初始化列表,只能写成下面这种形式才可以进行推导。
- template<typename T>
- void f(std::initializer_list<T> param);
复制代码 至于为什们,其实我也不清楚,也没有找到相关的资料,就只能当做一个规则记着吧。但是auto也不是那么完美,如果auto用于推导函数的返回类型,auto是不能推导初始化列表的。
- auto createInitList() { //C++14支持这种写法,C++11中需要结合decltype
- return { 1,2 ,3 };
- }
复制代码 除了不能作为函数返回值外,还不能作为lambda的参数,注意是lambda的参数,普通函数的参数是可以的,C++11中不支持lambda的参数使用auto,C++14开始支持。
- auto lda = [](const auto& v) {};
- lda({1,2,3}); //编译出错,无法推导初始化列表。
复制代码
|
|