• [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推断为你想要的类型
  • 相关阅读:
    Kth element of Two Sorted Arrays
    Populating Next Right Pointers in Each Node I && II
    Average waiting time of SJF and Round Robin scheduling
    LRU Cache
    Calculate H-index
    Get Level of a node in a Binary Tree
    Two Sum
    Intersection of Two Linked Lists
    Symmetric Tree
    Lowest Common Ancestor of Binary (Search) Tree
  • 原文地址:https://www.cnblogs.com/Azurewing/p/4740890.html
Copyright © 2020-2023  润新知