Possible Duplicate:
Why vector<bool>::reference doesn’t return reference to bool?
I used to think that with std::vector::operator[]
we get deep copies of the accessed item, but it seems that it is not always true. At least, with vector<bool>
the following test code gives a different result:
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
void Test(const T& oldValue, const T& newValue, const char* message)
{
cout << message << '\n';
vector<T> v;
v.push_back(oldValue);
cout << " before: v[0] = " << v[0] << '\n';
// Should be a deep-copy (?)
auto x = v[0];
x = newValue;
cout << " after: v[0] = " << v[0] << '\n';
cout << "-------------------------------\n";
}
int main()
{
Test<int>(10, 20, "Testing vector<int>");
Test<double>(3.14, 6.28, "Testing vector<double>");
Test<bool>(true, false, "Testing vector<bool>");
}
Output (source code compiled with VC10/VS2010 SP1):
Testing vector<int> before: v[0] = 10 after: v[0] = 10 ------------------------------- Testing vector<double> before: v[0] = 3.14 after: v[0] = 3.14 ------------------------------- Testing vector<bool> before: v[0] = 1 after: v[0] = 0 -------------------------------
I would have expected that v[0]
after the x = newValue
assignment would still be equal to its previous value, but this seems not true.
Why is that?
Why is vector<bool>
special?
operator[]
returns aT&
for every value ofT
except forbool
, where it gives a reference proxy. See this old column by Herb Sutter on why usingvector<bool>
in generic code is bad idea (and why it is not even a container). There is also a special Item about it in Effective STL by Scott Meyers, and tons of questions on it here at SO.vector<bool>
is a hideous abomination and special. The Committee specialized it to pack bits, therefore it does not support proper reference semantics, as you cannot refer to a bit, this means that it has a non-conforming interface and does not actually qualify as a Standard Container. The solution that most people use is simply to never, ever, usevector<bool>
.vector<bool>::operator[]
neither yields abool
nor a reference to abool
. It just returns a little proxy object that acts like a reference. This is because there are no references to single bits andvector<bool>
actually stores thebool
s in a compressed way. So by usingauto
you just created a copy of that reference-like object. The problem is that C++ does not know that this object acts as a reference. You have to force the "decay to a value" here by replacingauto
withT
.