Search code examples
c++c++11for-looprangeauto

Range-for-loops and std::vector<bool>


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)

Solution

  • 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 bools 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.