7

可能重复:
为什么 vector<bool>::reference 不返回对 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>特别?

4

3 回答 3

20

vector<bool>是一个可怕的可憎和特殊。委员会将其专门用于打包位,因此它不支持正确的引用语义,因为您不能引用位,这意味着它具有不符合标准的接口并且实际上不符合标准容器的资格。大多数人使用的解决方案就是永远不要使用vector<bool>.

于 2013-01-30T11:58:26.673 回答
6

vector<bool>::operator[]既不产生 abool也不产生对 a 的引用bool。它只是返回一个像引用一样的小代理对象。这是因为没有对单个位的引用,并且vector<bool>实际上bool以压缩方式存储 s。因此,通过使用auto您刚刚创建了该类引用对象的副本。问题是 C++ 不知道该对象充当引用。auto您必须通过替换为来强制“衰减到一个值” T

于 2013-01-30T12:03:50.870 回答
4

operator[]为except forT&的每个值返回一个,它提供一个引用代理。请参阅Herb Sutter 的这篇旧专栏,了解为什么在通用代码中使用是个坏主意(以及为什么它甚至不是容器)。Scott Meyers 在 Effective STL 中也有一个关于它的特殊项目,以及在 SO 上的大量问题。Tboolvector<bool>

于 2013-01-30T12:01:09.133 回答