下面的代码不编译
#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>
的设计师然后将面临一个选择
指定
std::vector<bool>::reference
支持所有的 操作=
并不断听到关于运行时效率低下的提示 使用这些运算符的程序员不支持那些操作
=
以及来自程序员的现场投诉,他们认为这些事情没问题(“更简洁的代码”等),即使它们效率低下。
看来 std::vector<bool>
的设计师选择选项 2。结果是 std::vector<bool>::reference
支持的唯一赋值运算符是库存标准operator=()
(具有 reference
类型或 bool
类型的操作数)不是任何 =
操作数.这种选择的优点是,如果程序员试图做一些在实践中实际上是糟糕选择的事情,就会出现编译错误。
毕竟,虽然bool
支持所有操作 =
无论如何,使用它们并没有太大的作用。例如,some_bool |= true
与 some_bool = true
具有相同的净效果.
关于c++ - std::vector<bool> 上的运算符 |=,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28882959/