可能重复:
Why vector<bool>::reference doesn’t return reference to bool?
我曾经认为使用std::vector::operator[]
我们会获得所访问项目的深度副本,但似乎并非总是如此。至少,对于vector<bool>
,以下测试代码会给出不同的结果:
#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>");
}
输出(使用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 -------------------------------
我希望 v[0]
赋值后的x = newValue
仍然等于其之前的值,但这似乎不正确。
这是为什么?
为什么vector<bool>
特别?
答案 0 :(得分:20)
vector<bool>
是一种可怕的憎恶和特殊。委员会专门用它来打包位,因此它不支持正确的引用语义,因为你不能引用一点,这意味着它有一个不符合的接口,实际上不符合标准容器的条件。大多数人使用的解决方案只是永远不会使用vector<bool>
。
答案 1 :(得分:6)
vector<bool>::operator[]
既不会产生bool
也不会引用bool
。它只返回一个代理对象,就像一个引用。这是因为没有对单个位的引用,而vector<bool>
实际上以压缩方式存储bool
。因此,通过使用auto
,您刚刚创建了类似引用的对象的副本。问题是C ++不知道这个对象充当引用。您必须将auto
替换为T
,强制将“衰减为值”。
答案 2 :(得分:4)
operator[]
为T&
的每个值返回T
,但bool
除外,它提供了参考代理。请参阅Herb Sutter的old column,了解为什么在通用代码中使用vector<bool>
是个坏主意(以及为什么它甚至不是容器)。 Scott Meyers在Effective STL中还有一个特别的项目,在这里有大量的questions。