c++ - std::vector<bool> 上的运算符 |=

标签 c++ bit-fields boolean-operations

下面的代码不编译

#include <vector>
int main()
{
  std::vector<bool> enable(10);
  enable[0] |= true;
  return 0;
}

报错

no match for ‘operator|=’ (operand types are ‘std::vector<bool>::reference {aka std::_Bit_reference}’ and ‘bool’)

在我的实际代码中,我有一个位字段,其中包含我想要 |= 函数结果的值。

有很简单的方法可以表达相同的想法,但是有什么充分的理由不提供这样的运算符吗?

最佳答案

主要原因是std::vector<bool>是特殊的,其规范明确允许实现最小化内存使用。

对于除 bool 以外的任何 vector ,引用类型实际上可以是真正的引用(即 std::vector<int>::reference 实际上可以是 int & )——通常直接引用 vector 本身的元素。因此,引用类型支持基础类型可以支持的所有操作是有意义的。这是有效的,因为 vector<int>有效管理 int 的连续数组在内部。除了 bool 之外的所有类型也是如此.

但是,为了尽量减少内存使用,一个 std::vector<bool>可能不会(事实上可能不会)在内部使用实际数组 bool .相反,它可能会使用一些压缩数据结构,例如 unsigned char 的数组。在内部,每个 unsigned char是一个包含 8 的位域位。所以一个vector<bool>长度为 800 的实际上管理一个 100 的数组unsigned char,它消耗的内存是100字节(假设没有过度分配)。如果vector<bool>实际上包含一个 800 的数组bool ,它的内存使用量将至少为 800字节(因为根据定义,sizeof(bool) 必须至少为 1)。

允许 vector<bool> 的实现者进行此类内存优化, vector<bool>::operator[] 的返回类型(即 std::vector<bool>::reference )不能简单地是 bool & .在内部,它可能包含对基础类型的引用(例如 unsigned char )和跟踪它实际影响的位的信息。这将使所有操作 =运算符( +=-=|= 等)对基础类型的一些昂贵的操作(例如位摆弄)。

std::vector<bool>的设计师然后将面临一个选择

  1. 指定std::vector<bool>::reference支持所有的 操作=并不断听到关于运行时效率低下的提示 使用这些运算符的程序员

  2. 不支持那些操作 =以及来自程序员的现场投诉,他们认为这些事情没问题(“更简洁的代码”等),即使它们效率低下。

看来 std::vector<bool> 的设计师选择选项 2。结果是 std::vector<bool>::reference 支持的唯一赋值运算符是库存标准operator=() (具有 reference 类型或 bool 类型的操作数)不是任何 = 操作数.这种选择的优点是,如果程序员试图做一些在实践中实际上是糟糕选择的事情,就会出现编译错误。

毕竟,虽然bool支持所有操作 =无论如何,使用它们并没有太大的作用。例如,some_bool |= truesome_bool = true 具有相同的净效果.

关于c++ - std::vector<bool> 上的运算符 |=,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28882959/

相关文章:

c++ - 视觉 C++ : Linking a DLL from another DLL using a relative path

c++ - Qt 5 : CONFIG+=c++11 vs QMAKE_CXXFLAGS+=-std=c++11 (What's better)

c++ - 结构中位域的值发生变化

c - 如何在 C 中使用 union 和 struc 将 float 转换为 IEEE754 double 格式?

c++ - C++静态成员的多态与继承

c++ - IMFTransform::ProcessOutput 效率

c++ - 位域成员的大小?

c++ - * 和 + 分别等同于 && 和 ||在 boolean 操作数上?

php - 使用 'or die()' 停止 PHP 中的错误

python - Pandas:将单列(字段)字符串替换为每个字符串一列