operator | = on std :: vector< bool> [英] operator |= on std::vector<bool>
问题描述
以下代码不编译
#include< vector&
int main()
{
std :: vector< bool> enable(10);
enable [0] | = true;
return 0;
}
出现错误
不匹配'operator | ='(操作数类型是'std :: vector< bool> :: reference {aka std :: _ Bit_reference}'和'bool')
在我的现实生活中的代码我有一个字段值,我想 | = / code>与一个函数的结果。
有很容易的方式来表达相同的想法,但有什么好的理由,
主要原因是 std :: vector< bool>
是特殊的,它的规范特别允许一个实现最小化内存使用。
对于 bool
,引用类型实际上可以是真实的引用(即 std :: vector< int> :: reference
实际上可以是 int &
) - 通常直接引用向量本身的元素。因此,引用类型支持基础类型可以执行的所有操作是有意义的。这是因为向量< int>
在内部有效地管理 int
的连续数组。对于除 bool
之外的所有类型也是如此。
但是,为了最小化内存使用, c> std :: vector< bool> 可能不会(实际上可能不会)在内部使用 bool
的实际数组工作。相反,它可能使用一些打包数据结构,例如内部的 unsigned char
数组,其中每个 unsigned char
位字段包含 8
位。因此长度为800的向量< bool>
实际上会管理一个 100
unsigned char数组,将 100
字节(假设没有过度分配)。如果向量< bool>
实际上包含 800
bool
,它的内存使用量最小为 800
字节(因为sizeof(bool)必须至少 1
为了允许向量< bool>
的实现者的这种存储器优化,返回类型 vector< bool> :: operator []
(即 std :: vector< bool> :: reference
) a bool&
。在内部,它可能包含对底层类型的引用(例如 unsigned char
)和跟踪实际影响的位的信息。这将使所有op =
运算符( + =
, - =
, | =
等等)底层类型上有些昂贵的操作(例如bit fiddling)。
那么 std :: vector< bool>
的设计者将面临
-
指定
std :: vector< bool> :: reference
支持所有
op=
-
不支持这些操作
= $>
specify that
std::vector<bool>::reference
support all the op=
and hear continual complaints about runtime inefficiency from programmers who use those operatorsDon't support those op
=
and field complaints from programmers who think such things are okay ("cleaner code", etc) even though they will be inefficient.
$ b
看来, std :: vector< bool>
的设计者选择了选项2.结果是, code> std :: vector operator =()
code>引用或类型 bool
)不是任何op =
。这种选择的优点是程序员得到编译错误,如果试图做一些实际上是一个糟糕的选择在实践中。
毕竟, bool
支持所有的操作 =
使用它们不会实现很多反正。例如, some_bool | = true
具有与 some_bool = true
相同的净效果。
The following code doesn't compile
#include <vector>
int main()
{
std::vector<bool> enable(10);
enable[0] |= true;
return 0;
}
giving the error
no match for ‘operator|=’ (operand types are ‘std::vector<bool>::reference {aka std::_Bit_reference}’ and ‘bool’)
In my real life code I have a bit field with values I want to |=
with the result of a function.
There are easy way to express the same idea, but is there any good reason for such an operator not to be available ?
The main reason would be that std::vector<bool>
is special, and its specification specifically permits an implementation to minimise memory usage.
For vectors of anything other than bool
, the reference type can actually be a true reference (i.e. std::vector<int>::reference
can actually be an int &
) - usually directly referencing an element of the vector itself. So it makes sense for the reference type to support all operations that the underlying type can. This works because vector<int>
effectively manages a contiguous array of int
internally. The same goes for all types other than bool
.
However, to minimise memory usage, a std::vector<bool>
may not (in fact probably will not) work internally with an actual array of bool
. Instead it might use some packed data structure, such as an array of unsigned char
internally, where each unsigned char
is a bitfield containing 8
bits. So a vector<bool>
of length 800 would actually manage an array of 100
unsigned char, and the memory it consumes would be 100
bytes (assuming no over-allocation). If the vector<bool>
actually contained an array of 800
bool
, its memory usage would be a minimum of 800
bytes (since sizeof(bool) must be at least 1
, by definition).
To permit such memory optimisation by implementers of vector<bool>
, the return type of vector<bool>::operator[]
(i.e. std::vector<bool>::reference
) cannot simply be a bool &
. Internally, it would probably contain a reference to the underlying type (e.g. a unsigned char
) and information to track what bit it actually affects. This would make all op=
operators (+=
, -=
, |=
, etc) somewhat expensive operations (e.g. bit fiddling) on the underlying type.
The designers of std::vector<bool>
would then have faced a choice between
It appears the designers of std::vector<bool>
opted for option 2. A consequence is that the only assignment operators supported by std::vector<bool>::reference
are the stock standard operator=()
(with operands either of type reference
, or of type bool
) not any of the op=
. The advantage of this choice is that programmers get a compilation error if trying to do something which is actually a poor choice in practice.
After all, although bool
supports all the op=
using them doesn't achieve much anyway. For example, some_bool |= true
has the same net effect as some_bool = true
.
这篇关于operator | = on std :: vector< bool>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!