以下代码无法编译
#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’)
在我的现实代码中,我有一个字段,其中包含我想要|=
的值以及函数的结果。
有一种简单的方法可以表达相同的想法,但是有没有充分的理由让这样的操作员无法使用?
答案 0 :(得分:4)
主要原因是std::vector<bool>
很特殊,其规范特别允许实现最小化内存使用。
对于bool
以外的任何向量,引用类型实际上可以是真正的引用(即std::vector<int>::reference
实际上可以是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}根据定义)。
为了允许1
的实施者进行此类内存优化,vector<bool>
的返回类型(即vector<bool>::operator[]
)不能简单地为std::vector<bool>::reference
。在内部,它可能包含对基础类型的引用(例如bool &
)和跟踪它实际影响的位的信息。这会使所有运算符unsigned char
运算符(=
,+=
,-=
等)对基础类型进行稍微昂贵的操作(例如bit fingdling)。
|=
的设计者将面临
指定std::vector<bool>
支持所有
op std::vector<bool>::reference
并听取关于运行时效率低下的持续抱怨
使用这些运算符的程序员
不要支持那些认为这些事情没事的程序员的=
和现场投诉(&#34;更干净的代码&#34;等),即使它们效率低下也是如此。
=
的设计人员似乎选择了选项2.结果是std::vector<bool>
支持的唯一赋值运算符是库存标准std::vector<bool>::reference
(操作数类型为{{} 1}},或类型operator=()
),而不是任何操作reference
。这种选择的优点是,如果尝试做一些在实践中实际上是不好选择的事情,程序员会遇到编译错误。
毕竟,虽然bool
支持使用它们的所有操作=
,但无论如何都不会取得多大成就。例如,bool
具有与=
相同的净效果。
答案 1 :(得分:1)
你为什么不这样做?
enable[0] = enable[0] | true;
答案 2 :(得分:1)
你应该可以很容易地自己制作一个。类似的东西:
std::vector<bool>::reference& operator |= (std::vector<bool>::reference& a, bool b)
{
if (b)
a = true;
return a;
}
或者,std::bitset非常合适。
答案 3 :(得分:0)
简短而甜蜜的回答:应该避免使用std::vector<bool>
。请改用vector<wchar>
。你实际上得到了一个容器,其中bool以比特打包,这给出了与其他向量不同的行为,慢速代码并且没有人关心回合内存。我想现在没有人喜欢这个了,但是倒转时钟会打破太多的代码......