这种扩展的动机是通过一致的程序可以检测到的,因此可以通过不一致的方式进行检测,从而使其vector<bool>
行为更像vector<char>
参考(const和其他)。
介绍
自1998年以来,vector<bool>
一直被嘲笑为“不是一个容器”。 LWG 96是最早的LWG问题之一,引发了这场辩论。17年后的今天,vector<bool>
基本上保持不变。
本文讨论了一些特定的示例,说明的行为vector<bool>
与的其他每个实例如何不同vector
,从而损害了通用代码。但是,同一篇文章详细讨论了vector<bool>
如果正确实现的话,非常好的性能属性。
摘要: vector<bool>
不是一个坏容器。实际上,它非常有用。它只是一个坏名字。
回到 const_reference
正如上面介绍的,并在此进行了详细介绍,不好的vector<bool>
是它在通用代码中的行为不同于其他vector
实例化。这是一个具体的例子:
#include <cassert>
#include <vector>
template <class T>
void
test(std::vector<T>& v)
{
using const_ref = typename std::vector<T>::const_reference;
const std::vector<T>& cv = v;
const_ref cr = cv[0];
assert(cr == cv[0]);
v[0] = 1;
assert(true == cv[0]);
assert(cr == cv[0]); // Fires!
}
int
main()
{
std::vector<char> vc(1);
test(vc);
std::vector<bool> vb(1);
test(vb);
}
标准规范说,带标记的assert // Fires!
会触发,但只有在test
使用时才触发vector<bool>
。当与运行vector<char>
(或任何vector
除了bool
当一个适当的非默认T
分配),测试通过。
libc ++实现试图使vector<bool>
在通用代码中行为不同的负面影响最小化。为此,它要做的一件事就是创建 vector<T>::const_reference
一个proxy-reference,就像指定的一样vector<T>::reference
,只是不能通过它进行分配。也就是说,在libc ++上,vector<T>::const_reference
它实际上是指向内的位的指针vector
,而不是该位的副本。
在libc ++上,以上都test
通过vector<char>
和vector<bool>
。
要花多少钱?
缺点是此扩展名是可检测的,如问题所示。但是,实际上很少有程序关心此别名的确切类型,而更多的程序关心行为。
这种不符合的动机是什么?
为了使libc ++客户端在通用代码中有更好的行为,并可能在经过充分的现场测试之后,建议将此扩展扩展到将来的C ++标准,以改善整个C ++行业。
这样的建议可以采用新容器的形式(例如bit_vector
),该容器具有与当今相同的API vector<bool>
,但有一些升级,例如const_reference
此处讨论的内容。随后弃用(并最终删除)该vector<bool>
专业化。 bitset
也可以在该部门进行一些升级,例如add const_reference
和一组迭代器。
也就是说,在事后bitset
是vector<bool>
(应该被重新命名为bit_vector
-或其他),为array
是vector
。而类比应该我们是否在谈论是成立的,bool
为value_type
的vector
和array
。
有多个C ++ 11和C ++ 14功能的示例,它们最初是libc ++中的扩展。这就是标准的演变方式。实际证明的 积极现场经验具有很强的影响力。在更改现有规范(应该如此)时,标准人群是一个保守派。猜测,即使您确定自己猜对了,也是发展国际公认标准的冒险策略。
vector<bool>
更一流的地位?