【问题标题】:how to tell auto to deduce a non reference type for element of vector<bool>如何告诉 auto 推断 vector<bool> 元素的非引用类型
【发布时间】:2019-12-13 17:41:14
【问题描述】:

代码如下:

int main()
{
    std::vector<bool> b(5,false);
    auto b0=b[0];
    cout<<b0;
    b[0]=true;
    cout<<b0;
    std::vector<int> i(5,false);
    auto i0=i[0];
    cout<<i0;
    i[0]=true;
    cout<<i0;

    return 0;
}

0100

变量 b0 是引用类型 (std::_Bit_reference) 而 i0 是普通 int。告诉 auto 推断一些非引用类型(例如 bool)的正确语法是什么?

【问题讨论】:

  • 我不认为你能做到这一点,因为auto 的具体意思是“拿起任何类型的东西”,而vector&lt;bool&gt; 是一个奇怪的东西。但也许我错了?
  • 也许 operator+ 工具可以在这里提供帮助?真正的解决方案是避免vector&lt;bool&gt;。试试vector&lt;Bool&gt;enum class Bool { False, True };

标签: c++ c++11 auto


【解决方案1】:

您将获得std::_Bit_reference,因为std::vectorbool 模板专业化(即std::vector&lt;bool&gt;)有一个“可能”节省空间的实现。

作为cppreference says,vector 以位而不是字节存储值:

使 std::vector 节省空间的方式(以及它是否被优化)是实现定义的。一种潜在的优化涉及合并向量元素,以便每个元素占用一个位而不是 sizeof(bool) 字节。

正如templatetypedef 所说,auto 采用它可以推断出的第一件事,这恰好是从比特中获取布尔值的一些奇特类型。

公开类 std::vector::reference 作为访问单个位的方法。特别是,这个类的对象由 operator[] 按值返回。


>operator bool() const;
>(until C++11)
>operator bool() const noexcept;
>(since C++11)
>Returns the value of the referenced bit.

它可以隐式转换为布尔值 (AFAIK),因此您不必担心将其传递给需要 bool 参数的函数。

【讨论】:

  • 我永远不会停止想知道为什么这个可憎的 std::vector&lt;bool&gt; 仍然是 STL 的一部分。
  • @TanveerBadar 我想最好添加一些其他专业化来明确声明布尔值经过优化以存储为位。我认为只是std::vector&lt;bool&gt; 是一个通常的向量。
  • 是的,它是std::bitset&lt;N&gt;。只有约束,N 在编译时是固定的。哦,它以另一种方式很糟糕。它可能不是 constexpr。
【解决方案2】:

auto 使用模板规则进行类型推导。你无法改变这一点。如果这不是你想要的,那么不要使用auto,而是手动写出类型

【讨论】:

    【解决方案3】:

    即使remove_reference也不能删除引用:

    #include <iostream>
    #include <vector>
    #include <typeinfo>
    
    using namespace std;
    
    int main()
    {
        std::vector<bool> b(5,false);
        std::remove_reference< decltype(b[0])>::type b0=b[0];
        cout<<typeid(b0).name()<< b0;
        b[0]=true;
        cout<<b0;
        return 0;
    }
    
    St14_Bit_reference01
    
    

    【讨论】:

    • 使用std::remove_reference 绝对没有意义,因为它删除了std::_Bit_reference 显然没有的引用限定符。在int&amp; 上使用的std::remove_reference 将简单地删除&amp;。但是std::_Bit_reference 不能作为参考——当没有&amp; 时,你不能删除它。这个类只是一个实现模拟一个引用behaviour
    猜你喜欢
    • 1970-01-01
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 2013-08-24
    • 2016-06-01
    • 1970-01-01
    相关资源
    最近更新 更多