std::vector<bool>
does not obey the standard container rules.
In particular, its iterators' operator*
do not return bool&
.
The loop in the invalid code
#include <vector>
#include <iostream>
int main() {
std::vector<bool> boolVector(10);
for (auto& i: boolVector)
std::cout << i;
}
can be rewritten in any of three ways to iterate through the values:
(read-only)
for (auto const i: boolVector)
std::cout << i;
(read-only, possibly inefficient¹)
for (auto const& i: boolVector)
std::cout << i;
(read/write²)
for (auto&& i: boolVector)
std::cout << i;
The choice between the first and last is down to whether you need to modify the values in the vector, or just to read them.
Notes:
I say "possibly inefficient" because it has an unnecessary level of indirection. Any decent optimizer ought to create the same code as for the first sample.
for (auto i: boolVector)
also gives a read/write view on the vector (because we have made a copy of the proxy object). But I don't recommend that, because readers will likely expect such writes to have only local effect, as would happen with standard containers.
And that's why I use auto const i
for the read-only case; alternatively we could obtain a proxy-of-const using boolVector | std::views::as_const
(since C++23) or by using a const reference to the vector (for (auto const& v = boolVector; auto i: v)
).