码迷,mamicode.com
首页 > 编程语言 > 详细

[Effective Modern C++] Item 6. Use the explicitly typed initializer idiom when auto deduces undesired types - 当推断意外类型时使用显式的类型初始化语句

时间:2015-08-19 00:03:49      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:

条款6 当推断意外类型时使用显式的类型初始化语句

基础知识

  当使用std::vector<bool>的时候,类型推断会出现问题:

std::vector<bool> features(const Widget& w);
// OK
bool highPriority = features(w)[5];
processWidget(w, highPriority); 
// ERROR
auto highPriority = features(w)[5];
processWidget(w, highPriority); // undefined behavior

  std::vector<bool>的operator[]操作并不返回一个bool类型,而是返回一个std::vector<bool>::reference(一个std::vector<bool>的内嵌类)。

  存在以上类型是因为std::vector<bool>返回紧凑形式的bool,每一位表示一个bool。vector的operator[]操作返回T&,但是C++静止引用为bit的形式。所以std::vector<bool>的operator[]操作返回一个类似bool&的对象std::vector<bool>::reference,并且隐式转换为bool。

  在使用auto时候,返回可能为一个指针以及偏移量,但随后指向出的内存会被释放,所以highPriority会变成一个悬垂指针(dangling pointer)。

  一些代理类十分明显,如std::shared_ptr和std::unique_ptr,有一些不明显如std::vector<bool>和std::bitset。

  C++中的有些库使用了一种叫做表达式模板(expression template)的技术来提高算术运算的效率。如Matrix + Matrix 返回一个代理类Sum<Matrix, Matrix>。

  在源代码中很难隐藏,所以可以通过以下方式识别代理:

namespace std {
    template<class Allocator>
    class vector<bool, Allocator> {
        public:
            class reference {};
            reference operator[](size_type n);
    };
} // 返回了reference类型

  可以使用显式类型初始化语句(explicitly typed initializer idiom)方式使用auto:

auto highPriority = static_cast<bool>(features(w)[5]);

总结

  • “不可见”的代理类型会导致auto推断初始化表达式时出现错误的类型
  • 显式类型初始化语句强制auto推断为你想要的类型

[Effective Modern C++] Item 6. Use the explicitly typed initializer idiom when auto deduces undesired types - 当推断意外类型时使用显式的类型初始化语句

标签:

原文地址:http://www.cnblogs.com/Azurewing/p/4740890.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!