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.