• [Effective Modern C++] Item 6. Use the explicitly typed initializer idiom when auto deduces undesired types


    条款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推断为你想要的类型
  • 相关阅读:
    layui2.5 修改layuicms
    linux ubuntu安装node npm cnpm nvm nrm yarn vue-cli vue-router
    浅析微信支付:(余额提现)企业付款到微信用户零钱或银行卡账户
    pdo类的使用
    生成url的二维码图片
    点击提交按钮后 禁用提交按钮3秒后 再启用
    Maven项目Update Project后JRE System Library自动变回1.5解决办法
    一步步搭建 Spring Boot maven 框架的工程
    AspectJ报错:error at ::0 can't find referenced pointcut XXX
    SpringBoot 文件上传实践
  • 原文地址:https://www.cnblogs.com/Azurewing/p/4740890.html
Copyright © 2020-2023  润新知