繁体   English   中英

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

[英]operator |= on std::vector<bool>

以下代码无法编译

#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向量,引用类型实际上可以是真正的引用(即std::vector<int>::reference实际上可以是int & )-通常直接引用向量本身的元素。 因此,对于引用类型,支持基础类型可以进行的所有操作是有意义的。 之所以vector<int>是因为vector<int>内部有效地管理了一个连续的int数组。 bool以外的所有类型都一样。

但是,为了最大程度地减少内存使用, std::vector<bool>可能无法(实际上可能不会)在内部实际与bool数组一起工作。 相反,它可能使用某些打包数据结构,例如内部的unsigned char数组,其中每个unsigned char都是一个包含8位的位字段。 因此,长度为800的vector<bool>实际上将管理100无符号字符的数组,并且它消耗的内存为100个字节(假设没有过度分配)。 如果vector<bool>实际上包含800 bool数组,则其内存使用量将至少为800个字节(因为按定义,因为sizeof(bool)必须至少为1 )。

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

然后, std::vector<bool>的设计人员将面临以下选择:

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

  2. 不要支持那些认为这样的事情没问题(尽管效率低下)的程序员的op =和field抱怨。

似乎std::vector<bool>的设计者选择了选项2。结果是std::vector<bool>::reference支持的唯一赋值运算符是标准的标准operator=() (操作数为类型referencebool类型)op =任何一个。 这种选择的优点是,如果尝试执行实际上在实践中不佳的选择,则程序员会遇到编译错误。

毕竟,尽管bool支持所有op = ,但使用它们并不能取得多大成就。 例如, some_bool |= true具有与some_bool = true相同的净效果。

您为什么不只执行以下操作?

enable[0] = enable[0] | true;

您应该能够轻松地使自己变得很漂亮。 就像是:

std::vector<bool>::reference& operator |= (std::vector<bool>::reference& a, bool b)
{
    if (b)
       a = true;
    return a;
}

另外, std :: bitset非常适合。

简短的回答:应该避免std::vector<bool> 改用vector<wchar> 实际上,您会得到一个容器,其中的布尔变量是按位打包的,这赋予了与其他矢量不同的行为,缓慢的代码,而且无论如何都没有人关心回合内存。 我猜现在没有人喜欢这个了,但是倒转时钟会破坏太多的代码...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM