Q:

Ranged based for loop for vector of booleans

std::vector<bool> uses proxy iterators. 
So the following code will not compile (code taken from the accepted answer in related question ):
vector<bool> v = {true, false, false, true};
for (auto& x : v)
    x = !x;

In the related question, the accepted answer states that to modify the components of the vector in place, we must use 
for (auto&& x : v)
    x = !x;

But if I simply do:
for (auto x : v)
    x = !x;

This produces identical results. So is the && not needed?
Further why does the following 2 codes not modify the components?
for (bool &&x : v)
    x = !x;

and 
for (bool x : v)
    x = !x;

A:

TL;DR: The proxy object knows how to read and write the single bits, regardless of how you keep it. Converting the proxy object to bool loses that information.

for (auto&& x : v)
    x = !x;

and
for (auto x : v)
    x = !x;

have the same behavior because in each case the proxy object (std::vector<bool>::reference) obtained from dereferencing a std::vector<bool>::iterator is stored in x. Whether the proxy object is stored by value or reference doesn't matter - its behavior of modifying the proxied bit is the same.
In
for (bool &&x : v)
    x = !x;

and 
for (bool x : v)
    x = !x;

the proxy object is implicitly converted to a bool. This necessarily loses the information needed (and thus the capability) to affect the compressed bit.
Note that these are all implementation-defined. Your implementation is allowed to forego the space optimization too, in which case the behavior you see could be different. Only auto&& works in every case.

