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?
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, use vector<bool>
.
vector<bool>::operator[]
neither yields a bool
nor a reference to a bool
. It just returns a little proxy object that acts like a reference. This is because there are no references to single bits and vector<bool>
actually stores the bool
s in a compressed way. So by using auto
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 replacing auto
with T
.
operator[]
returns a T&
for every value of T
except for bool
, where it gives a reference proxy. See this old column by Herb Sutter on why using vector<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.
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