c – 多个代理类可以构成一个STL保护位向量吗?

这是 well known std :: vector< bool>不符合标准的容器要求,主要是因为打包表示防止T * x =& v [i]返回指针到bool.

我的问题是:当reference_proxy重载运算符&的地址时,可以补救/减轻要返回一个pointer_proxy?

指针代理可以在大多数实现中包含与reference_proxy相同的数据,即指向打包数据的指针和用于隔离指向的块内的特定位的掩码. pointer_proxy的间接方法将产生reference_proxy.基本上两个代理都是“胖”指针,但是与基于磁盘的代理容器相比,它们仍然相当轻.

而不是T * x =& v [0],则可以自动执行自动x =& v [0],并且像x(x)一样使用x而没有问题.我也想写(auto b:v){/ * … * /}

问题:这种多代理方法能否与ST​​L的算法配合使用?或者做一些算法真的依赖于x需要成为一个真正的bool *的要求?或者是否需要太多连续的用户定义的转换来阻止这种转换?在想完全完成上述实施草图之前,我想知道这些障碍物.

UPDATE(基于@HowardHinnant的答案和这个ancient discussion在comp.std.c上)

你可以通过很长的一段时间来模拟内置的类型:对于任何给定的类型T,一个代理(例如,reference_proxy和iterator_proxy)可以相互一致,即reference_proxy :: operator&()和iterator_proxy :: operator *()彼此相反.

然而,在某些时候,需要将代理对象映射到T *或T& amp;对于迭代器代理,可以重载operator>()并访问模板T的接口,而无需重新实现所有功能.但是,对于参考代理,您需要重载运算符.(),并且不允许在当前C(尽管Sebastian Redl presented such a proposal on BoostCon 2013).您可以像引用代理中的.get()成员一样进行详细的工作,或者在引用内部实现T的所有接口(这是对vector :: bit_reference所做的),但是这将丢失内置语法或者引入没有用于类型转换的内置语义的用户定义的转换(每个参数最多可以有一个用户定义的转换).

解决方法

My question is: can this be remedied/mitigated when the
reference_proxy overloads the address-of operator& to return a
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);
}

它甚至以向模式< int>模拟相同类型的方式扩展到const_pointer和const_reference.这是libc的不合规格扩展.但是它使得编写可能在向量< bool>上实例化的通用代码更有可能编译和行为正确.

Questions: would such a multi-proxy approach work with the STL’s
algorithms? Or do some algorithms really rely on the requirement that
x needs to be a real bool*? Or are there too many consecutive
user-defined conversions required that prevent this to work?

所有libc的算法都使用向量< bool&gt ;.其中一些与quite spectacular performance.一个算法特别是必须有特殊待遇,该标准不幸地不要求:

#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);
}

这对于实现来说非常容易.只需要确保交换适用于bool和向量< bool> :: reference的任何组合.但是我不知道除了libc之外的任何实现是不是这样做,而不是由C11规定.

位数组是一个奇妙的数据结构.但不幸的是,它在C标准中不太明确. libc已经有些非法,以证明这可以是一个非常有用和高性能的数据结构.希望未来的C标准可能在这个方向上迁移到C程序员的利益.

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录&lt;future&gt;future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...