Why does this code work
std::vector<int> intVector(10); for(auto& i : intVector) std::cout << i;
And this doesn't?
std::vector<bool> boolVector(10); for(auto& i : boolVector) std::cout << i;
In the latter case, I get an error
error: invalid initialization of non-const reference of type ‘std::_Bit_reference&’ from an rvalue of type ‘std::_Bit_iterator::reference {aka std::_Bit_reference}’
for(auto& i : boolVector)
C++11 introduced the ranged for loop. This for loop is specifically used with collections such as arrays and vectors. Here, the ranged for loop iterates the array num from beginning to end. The int variable var stores the value of the array element in each iteration.
Range-based for loop in C++ Range-based for loop in C++ is added since C++ 11. It executes a for loop over a range. Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container.
Range-for is as fast as possible since it caches the end iterator[citationprovided], uses pre-increment and only dereferences the iterator once. Then, yes, range-for may be slightly faster, since it's also easier to write there's no reason not to use it (when appropriate).
Remarks. Use the range-based for statement to construct loops that must execute through a range, which is defined as anything that you can iterate through—for example, std::vector , or any other C++ Standard Library sequence whose range is defined by a begin() and end() .
Because std::vector<bool>
is not a container !
std::vector<T>
's iterators usually dereference to a T&
, which you can bind to your own auto&
.
std::vector<bool>
, however, packs its bool
s together inside integers, so you need a proxy to do the bit-masking when accessing them. Thus, its iterators return a Proxy
.
And since the returned Proxy
is an prvalue (a temporary), it cannot bind to an lvalue reference such as auto&
.
The solution : use auto&&
, which will correctly collapse into an lvalue reference if given one, or bind and maintain the temporary alive if it's given a proxy.
std::vector<bool>
does not obey the standard container rules.
In particular, its operator[]
does 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 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With