Tem*_*Rex 11 c++ containers stl proxy-classes bitvector
它是众所周知的是std::vector<bool>
不符合标准的容器的需求,主要是因为打包表示防止T* x = &v[i]
从一个指针返回一个布尔值.
我的问题是:当reference_proxy重载address-of operator&
以返回pointer_proxy 时,这可以得到补救/缓解吗?
在大多数实现中,指针代理可以包含与reference_proxy相同的数据,即指向打包数据的指针和用于隔离指向的块内的特定位的掩码.然后,pointer_proxy的间接将产生reference_proxy.基本上两个代理都是"胖"指针,然而,与基于磁盘的代理容器相比,这些指针仍然相当轻.
而不是T* x = &v[0]
一个会然后做auto x = &v[0]
,并使用x
像if(*x)
没有问题.我也希望能够写作for(auto b: v) { /* ... */ }
问题:这种多代理方法是否适用于STL的算法?或者某些算法真的依赖于x
需要真实的需求bool*
?或者是否有太多连续的用户定义转换需要阻止它工作?在尝试完全完成上述实施草图之前,我想知道任何这样的障碍物.
更新(基于@HowardHinnant的回答和关于comp.std.c ++的古老讨论)
你可以在很大程度上模仿内置类型:对于任何给定的类型T,一对代理(例如reference_proxy和iterator_proxy)可以在reference_proxy :: operator&()和iterator_proxy :: operator*的意义上相互一致. ()是彼此相反的.
但是,在某些时候,需要将代理对象映射回来以表现为T*或T&.对于迭代器代理,可以重载operator - >()并访问模板T的接口,而无需重新实现所有功能.但是,对于参考代理,您需要重载operator.(),这在当前C++中是不允许的(尽管Sebastian Redl在BoostCon 2013上提出了这样的提议).您可以像引用代理中的.get()成员一样进行冗长的解决方法,或者在引用中实现所有T的接口(这是对vector :: bit_reference所做的),但这会丢失内置语法或引入用户定义的转换,这些转换没有用于类型转换的内置语义(每个参数最多只能有一个用户定义的转换).
我的问题是:当reference_proxy重载address-of运算符并返回pointer_proxy时,这可以得到补救/缓解吗?
libc ++实际上是这样做的.
#include <vector>
#include <cassert>
int main()
{
std::vector<bool> v(1);
std::vector<bool>::pointer pb = &v[0];
assert(*pb == false);
*pb = true;
assert(v[0] == true);
std::vector<bool>::const_pointer cbp = pb;
assert(*cbp == true);
v[0] = false;
assert(*cbp == false);
}
Run Code Online (Sandbox Code Playgroud)
它甚至延伸到const_pointer
并const_reference
在模仿同类型的方式vector<int>
.这是libc ++的不合规扩展.但它使得编写可能实例化的通用代码vector<bool>
更有可能编译和正确运行.
问题:这种多代理方法是否适用于STL的算法?或者一些算法真的依赖于x需要成为真正的bool*的要求?或者是否有太多连续的用户定义转换需要阻止它工作?
所有libc ++的算法都可以使用vector<bool>
.其中一些表现非常出色.特别是一种算法必须有特殊的处理方法,遗憾的是标准不能强制执行:
#include <vector>
#include <cassert>
int main()
{
std::vector<bool> v(1);
bool b = true;
assert(v[0] == false);
assert(b == true);
std::swap(b, v[0]);
assert(v[0] == true);
assert(b == false);
}
Run Code Online (Sandbox Code Playgroud)
实现这很容易实现.一个只需要确保swap
作品的任意组合bool
和vector<bool>::reference
.但是我不知道除了libc ++之外是否有任何实现这样做,并且它不是C++ 11强制要求的.
位数组是一种很棒的数据结构.但不幸的是,它在C++标准中的指定很差.libc ++在某种程度上是非法的,以证明这可以是一个非常有用和高性能的数据结构.希望未来的C++标准可以向这个方向迁移,以使C++程序员受益.