vector<bool>
is special. Unlike vectors of other types, it doesn't store actual bool
s (that would require using 1 byte per bool
). Instead, it stores them packed as bits in an array of integers (1 bit per value; for example, it might store an array of unsigned char
and pack 8 bool
s as bits into a single unsigned char
).
Because there are no actual bool
s in the vector<bool>
, you can't form references to them. So the operations that would normally yield references (such as dereferencing an iterator) can't do so.
Some experts told me the reference of vector<bool>
is prvalue. Though I do not understand it at all. But as their high bonus on SO, I believe they are right.
What they mean is that dereferencing a vector<bool>
iterator returns a prvalue (which simply means that it returns by value rather than by reference).
By "reference of vector<bool>
" they likely meant vector<bool>::reference
and vector<bool>::const_reference
, which refer to the types that you get when dereferencing an iterator (regular and const respectivelty) of vector<bool>
. Normally, for vector<T>
(T != bool
) they would be equal to T &
and const T &
respectively, but for vector<bool>
, const_reference
is bool
and reference
is some class.
The vector<bool>::reference
class has some overloaded operators to make it work like a reference. In particular, it has operator=
overloaded, so you can assign bool
s to it. (Which sets a single specific bit of the vector to 1
.)
As for why for (auto&& e : v)
works... auto &&
is a forwarding reference. I'm not going to explain how forwarding references work (look it up!), but your loop is equivalent to for (std::vector<bool>::reference &&e : v)
(if it wasn't a vector of bool
, it would instead become for (ElementType &e : v)
).
When you do e = false;
, you invoke the overloaded operator=
of std::vector<bool>::reference
.