vector <bool> :: operator [] misbehavior?</bool>

时间:2013-01-30 11:56:09

标签: c++ vector c++11 boolean auto

  

可能重复:
  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>特别?

3 个答案:

答案 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