众所周知,它std::vector<bool>
不满足标准的容器要求,主要是因为打包表示阻止T* x = &v[i]
返回指向布尔值的指针。
我的问题是:当reference_proxy 重载address-of以返回pointer_proxy时,这可以补救/缓解吗?operator&
在大多数实现中,指针代理可以包含与 reference_proxy 相同的数据,即指向打包数据的指针和用于隔离块内指向的特定位的掩码。然后,pointer_proxy 的间接生成将产生 reference_proxy。本质上,这两个代理都是“胖”指针,但是与基于磁盘的代理容器相比,它们仍然相当轻量级。
而不是T* x = &v[0]
一个人可以这样做auto x = &v[0]
,并且使用x
likeif(*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 所做的),但这会丢失内置语法或引入没有用于类型转换的内置语义的用户定义的转换(每个参数最多可以有一个用户定义的转换)。