Item2 Understand auto type deduction【Effective Modern C++中文版】

[复制链接]

该用户从未签到

759

主题

763

帖子

4660

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4660
跳转到指定楼层
楼主
发表于 2018-1-5 19:29:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

想要查看内容赶紧注册登陆吧!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
在Item1中介绍了C++98的模板类型推导,而C++11中引入的auto其类型推导规则和模板类型是如出一辙的。在Item1中提到的模板类型推导规则可以总结为如下形式:
  1. template<typename T>
  2. void f(`参数类型` param)

  3. f(var)
复制代码
根据参数类型和传入的var的类型的不同,推导的规则也相应不同,那么auto是如何和模板推导规则关联呢?
  1. auto x = 27             //对应Item1中的Case3,x的类型就是int
  2. int& z = x;
  3. const int y = 19;
  4. auto cx = x;            //对应Item1中的Case3,cx的类型就是int,忽略了y的CV限制符和引用等
  5. const auto& rx = z;     //对应Item1中的Case1,rx的类型是const引用类型,忽略z的引用
  6. auto&& rrx = 27         //对应Item1中的Case2,rrx的类型int&&

  7. 参数类型 param = var
复制代码
auto可以总结为上面这种形式。根据赋值操作右边的var类型,和变量名左边的参数类型结合起来进行推导。在Item1中还提到了两个额外的类型推导,一个是数组类型,另外一个是函数类型。对应到auto则如下:
  1. const char name[] = "test";
  2. auto arr1 = name;       //arr1的类型是const char*类型
  3. auto& arr2 = name;      //arr2的类型是const char(&)[5]

  4. void someFunc(int,doubel);
  5. auto func1 = someFunc;  //void(*)(int,double)
  6. auto& func2 = someFunc; //void(&)(int,double)
复制代码
除了上面提到的推导规则外,auto还有一个和模板类型推导不一样的地方。这也是本节Item需要关注的。在C++11中引入了统一初始化列表,相对应的则是std::initializer_list<T>模板类型。
  1. auto  x1 = {1,2,3}; //此时x1被推导为std::initializer_list<T>
复制代码
因为初始化列表是模板类型,因此所有的元素必须是同一类型,否则会初始化失败。对应到模板类型推导如下:
  1. auto x = {11,23,9}
  2. template<typename T>
  3. void f(T param);

  4. f(x);   //编译错误,无法进行推导。
复制代码
模板类型推导居然无法识别初始化列表,只能写成下面这种形式才可以进行推导。
  1. template<typename T>
  2. void f(std::initializer_list<T> param);
复制代码
至于为什们,其实我也不清楚,也没有找到相关的资料,就只能当做一个规则记着吧。但是auto也不是那么完美,如果auto用于推导函数的返回类型,auto是不能推导初始化列表的。
  1. auto createInitList() {     //C++14支持这种写法,C++11中需要结合decltype
  2.     return { 1,2 ,3 };
  3. }
复制代码
除了不能作为函数返回值外,还不能作为lambda的参数,注意是lambda的参数,普通函数的参数是可以的,C++11中不支持lambda的参数使用auto,C++14开始支持。
  1. auto lda = [](const auto& v) {};
  2. lda({1,2,3});   //编译出错,无法推导初始化列表。
复制代码


分享到:  QQ好友和群QQ好友和群
收藏收藏
回复

使用道具 举报

快速回复高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表