向量<bool>::operator[] 不当行为?

2022-01-19 00:00:00 boolean vector c++ c++11 auto
<块引用>

可能重复:
为什么vector<bool>::reference不返回对bool的引用?

我曾经认为使用 std::vector::operator[] 我们可以获得访问项目的 deep 副本,但似乎并非总是如此.至少,使用 vector<bool> 以下测试代码会给出不同的结果:

#include <iostream>#include <向量>使用命名空间标准;模板<typename T>void Test(const T& oldValue, const T& newValue, const char* message){cout <<消息 <<'
';载体<T>五;v.push_back(oldValue);cout <<" 之前:v[0] = " <<v[0] <<'
';//应该是深拷贝 (?)自动 x = v[0];x = 新值;cout <<" 之后:v[0] = " <<v[0] <<'
';cout <<"-------------------
";}主函数(){测试<int>(10, 20, "测试向量<int>");测试<double>(3.14, 6.28, "测试向量<double>");测试<bool>(true, false, "测试向量<bool>");}

输出(用VC10/VS2010 SP1编译的源代码):

<块引用>

测试向量之前:v[0] = 10之后:v[0] = 10-------------------------------------------测试向量<double>之前:v[0] = 3.14之后:v[0] = 3.14-------------------------------------------测试向量<bool>之前:v[0] = 1之后:v[0] = 0-------------------------------------------

我本来希望 v[0] after x = newValue 赋值仍然等于它之前的值,但是这似乎不是真的.这是为什么?vector<bool> 为什么特别?

解决方案

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

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 << '
';

    vector<T> v;
    v.push_back(oldValue);
    cout << " before:  v[0] = " << v[0] << '
';

    // Should be a deep-copy (?)       
    auto x = v[0];   
    x = newValue;

    cout << " after:   v[0] = " << v[0] << '
';
    cout << "-------------------------------
";
}

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>::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 bools 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.

相关文章