C++ 对标准库分配器指针类型的要求

C++ 对标准库分配器指针类型的要求,c++,standard-library,allocator,language-lawyer,C++,Standard Library,Allocator,Language Lawyer,我正在尝试编写一个四叉树稀疏矩阵类。简言之,四叉树矩阵是零矩阵或四叉树矩阵的四叉树(ne、nw、se、sw) 我希望最终测试不同的分配方案,因为这可能会影响线性代数运算的性能。因此,我还将在标准分配器类型上模板化quadtree\u matrix,以便重用现有分配器 我必须分配两种不同类型的数据:要么是T,要么是节点,其中包含四个指针(指向T或节点)。对于所有的算法,我会考虑,我知道什么样的数据期望,因为我知道什么是子矩阵的大小,我面临的任何点的算法(我甚至不需要存储这些大小)。 当然,我将使用

我正在尝试编写一个四叉树稀疏矩阵类。简言之,
四叉树矩阵
是零矩阵或
四叉树矩阵
的四叉树(ne、nw、se、sw)

我希望最终测试不同的分配方案,因为这可能会影响线性代数运算的性能。因此,我还将在标准分配器类型上模板化
quadtree\u matrix
,以便重用现有分配器

我必须分配两种不同类型的数据:要么是
T
,要么是
节点
,其中包含四个指针(指向T或节点)。对于所有的算法,我会考虑,我知道什么样的数据期望,因为我知道什么是子矩阵的大小,我面临的任何点的算法(我甚至不需要存储这些大小)。 当然,我将使用两种不同的分配器:这是可以的,因为分配器类型提供了
rebind
模板和一个模板副本构造函数(并且打算用作值类型,正如标准容器的
get\u分配器
成员通过返回副本所建议的那样)

问题是分配器成员函数使用了某种
指针
类型,这不一定是普通指针。一些分配器(boost进程间分配器)广泛使用此功能

如果分配器指针类型是各种各样的指针,我就不会有任何问题:至少,我可以使用指针来作废并将它们重新解释为正确的类型(无论是
node*
还是
T*
)。我也可以使用工会(可能更好)

据我所知,对
allocator::pointer
类型的PODness没有要求。它们只需要是随机访问迭代器

现在,我的问题是:

给定一个分配器类模板
A
(或其等价物
A::rebind::other
),是否有任何保证:

  • 静态转换
    A::pointer
    A::pointer
    的能力提供了
    U
    T
    的可访问基础。
  • 静态转换
    A::pointer
    A::pointer
    的能力提供了
    T
    U
    的一个可访问的基础,castee的“运行时类型”(在此上下文中的任何含义)是
    U
  • 类型
    A::pointer
    (如果这有意义)
  • 或者我的问题有没有我没有想到的解决方案?

    没有,没有

    有一个要求:指针可以转换为::const_指针和::void_指针,但这就是我所能找到的全部


    A::pointer很可能是
    void*
    ,除非您有一些奇特的特殊内存。

    从20.1.5/2中的表中可以清楚地看出
    A::pointer
    的类型必须是“指向
    T
    ”的指针。因为这些指针类型通常是可转换的,所以1和2是真的。接下来,指针
    A::pointer
    必须是
    void*

    编辑: 20.1.5/4中也有明确的措辞(它适用于标准容器对分配器的假设):

    typedef成员指针, 常量指针、大小类型和 差异类型必须是 T*、T常数*、尺寸和公差, 分别


    请注意,即使
    联合可用,我仍然不会使用它,特别是因为在这里,您可能会受益于某种形式的自动内存管理(为了使您的contain不泄漏),这需要一些奇特的类

    因此,我建议采取两步办法:

    • 编写一个使用给定分配器执行销毁的小型智能指针(而不是
      delete
    • 在指针上使用
      boost::variant

    这样,您既有自动内存管理又有compacity

    ,所以就没有空间容纳奇特的内存分配器了?Boost进程间共享内存分配器返回一个
    offset\u ptr
    类型,它不是一个T*而是一个随机迭代器。@Alexandre:我相信Boost文档中他们实际上引用了这一点,这是Boost进程间无法提供标准分配器和需要自定义容器的原因之一。好的,所以我假设它们是真正的指针。我担心的是第三方分配器类可能不会使用真正的指针类型作为
    指针
    。既然允许标准容器类假设这一点,那么我将这样做。谢谢你的回答!我不想要boost variant的运行时安全性(它添加了一个标志),也不想在每个指针旁边引用分配器。这会增加每个节点的开销(这意味着6n开销,而不是4n,n=非零条目的数量)。我可以很好地(事实上,如果我不想在头顶上留下空间的话,我必须)用手来处理容器的销毁。事实上,我没有具体说明这一点。我想将四叉树方案与“传统”稀疏矩阵算法进行比较。这个类本身很容易使用,但它的实现却不能。@Alexandre C:我理解:)这是你的努力:p