向量<bool>::运算符[] 不当行为?
vector<bool>::operator[] misbehavior?
可能的重复项:
为什么vector::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 -------------------------------
我本以为x = newValue
赋值后的v[0]
仍然等于其先前的值,但这似乎不是真的。为什么?为什么vector<bool>
特别?
vector<bool>
是一个可怕的可憎和特殊的东西。委员会专门将其用于打包位,因此它不支持正确的引用语义,因为您无法引用位,这意味着它具有不符合要求的接口,并且实际上不符合标准容器的条件。大多数人使用的解决方案只是 永远不要使用vector<bool>
.
vector<bool>::operator[]
既不产生bool
,也不产生对bool
的引用。它只返回一个充当引用的小代理对象。这是因为没有对单个位的引用,vector<bool>
实际上以压缩方式存储bool
。因此,通过使用auto
您只是创建了该类似引用的对象的副本。问题是C++不知道这个对象充当参考。您必须通过将auto
替换为T
来强制"衰减到一个值"。
operator[]
为T
的每个值返回一个T&
,除了bool
,它给出了一个引用代理。请参阅Herb Sutter的这个旧专栏,了解为什么在通用代码中使用vector<bool>
是一个坏主意(以及为什么它甚至不是一个容器)。斯科特·迈耶斯(Scott Meyers)在Effective STL中还有一个关于它的特殊项目,在SO这里有很多关于它的问题。
- 理解boost::asio-async_read在无需读取内容时的行为
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- arr[-1]在c++中的奇怪行为
- 继承期间显示未知行为的子类
- 如何在c++中使用引用实现类似python的行为
- G锁定铸造到基础上会释放模拟行为
- 在C++中对T*类型执行std::move的意外行为
- std::当在256字节边界上写入整数时,流的奇怪行为
- 不知道某个东西是否被忽略会引入未定义的行为吗
- 奇怪的构造函数行为
- 重载运算符new[]的行为取决于析构函数
- 不同语言中相同代码的不同行为
- 在软呢帽的管道stock鱼不当行为
- 快速 XML 解析不当行为
- 查看实施不当行为
- 计时器、线程和编译器不当行为
- 将函数地址转换为 64 位整数:未定义/行为不当
- 由于内存重用不当而导致的未定义行为
- 向量<bool>::运算符[] 不当行为?
- 为什么这个initializer_list在传递字符串时使用不当行为