条款6:当auto推导的类型不符合要求时,使用带显示类型的初始化物习惯手法

有时候,你想往东,auto类型推导的结果偏偏往西。考虑如下代码:

std::vector<bool> features(cosnt Widget& w);
Widget w;
bool highPriority = features(w)[5]; 
processWidget(w, hightPrioirty);

上述代码没有什么问题,如果我们吧highPriority从显示类型改为auto呢?

auto highPriority = featrues(w)[5];

所有代码仍然可编译,但是其行为则变得不再可以预测了

processWidget(w, hightPrioirty); //未定义行为

上述函数调用中,highPriority的类型不再是bool了。它返回的是std::vector<bool>::reference类型的对象。之所以要弄出个std::vector<bool>::reference,是因为std::vector<bool>做过特化,用了一种压缩形式表示其持有bool元素,每个bool元素用一个比特来表示。这种做法给std::vector<T>operator[]带来一个问题,因为按说std::vector<T>operator[]应该返回T&,然而C++中给你却禁止比特的引用。、

auto highPriority = featrues(w)[5];

features的调用会返回一个std::vector<bool>类型的临时对象temp,针对temp执行operator[],返回一个std::vector<bool>::reference类型对象,该对象含有一个指涉及到机器字的指针,该机器字在一个持有temp所管理的那样比特币的数据结构中,还要加上第5个比特所对应的机器字的偏移量。由于highPrioritystd::vector<bool>::reference对象的一个副本,所以highPriority也含有一个指涉到temp中的机器字的指针,加上还要在第5个比特所对应的机器字的偏移量。在表达式结束处,temp会被析构,因为它是一个临时对象。结果,highPriority会含有一个空悬指针,最终导致processWidget时出现未定义行为。

std::vector<bool>::reference是一个代理类的实例。所谓代理类,就是为了模拟或增广其他类型的类;所以我们要防止写出以下这样的代码

auto someVar = "隐形"代理类型表达式
auto highPriority = static_cast<bool>featrues(w)[5]; //是一种安全做法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值