[英]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>
的设计人员将面临以下选择:
指定std::vector<bool>::reference
支持所有op =
并听到使用这些运算符的程序员不断抱怨运行时效率低下
不要支持那些认为这样的事情没问题(尽管效率低下)的程序员的op =
和field抱怨。
似乎std::vector<bool>
的设计者选择了选项2。结果是std::vector<bool>::reference
支持的唯一赋值运算符是标准的标准operator=()
(操作数为类型reference
或bool
类型)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.