【问题标题】:Using custom allocator for AllocatorAwareContainer data members of a class为类的 AllocatorAwareContainer 数据成员使用自定义分配器
【发布时间】:2016-01-01 22:19:09
【问题描述】:

给定一个非无状态自定义分配器A(例如,arena 分配器,绑定到一些运行时已知大小的连续内存块)和类S,包含AllocatorAwareContainer 类型的文件:

struct S
{
    A() = default;
    // another c-tors
    std::vector< T > v;
    std::shared_ptr< U > s;
};

我想将A 用于S 类的子集(甚至所有)AllocatorAwareContainer 字段。很明显,我应该为S类提供另一个模板参数,并相应地更改所有感兴趣的数据成员的类型,如下所示:

template< typename A = std::allocator< void > >
struct S
{
    // c-tors
    template< typename X >
    using allocator = typename std::allocator_traits< A >::template rebind< X >::other;
    std::vector< T, allocator< T > > v;
    std::shared_ptr< U, allocator< U > > s;
};

我应该对现有构造函数和其他构造函数进行哪些更改(假设 A 不是 DefaultConstructible 并且可能存在任何其他可能的限制)?

我应该将分配器A 存储在S 类的附加字段中吗?

为类使用自定义分配器的一般技巧是什么?

【问题讨论】:

    标签: c++ memory-management stl c++14 allocator


    【解决方案1】:

    我习惯于使用来自bsl 的可识别分配器的容器,并习惯于创建可识别分配器的类。与标准容器及其分配器使用的主要区别在于 bsl 使用指向分配器基类 (bslma::Allocator) 的指针。这种方法很好地摆脱了std::rebind-dance,它使已经相对复杂的领域中的事情变得复杂。否则,我认为这些概念可以翻译。我没有在标准库容器中使用分配器的经验。

    分配器的使用有两条基本规则在实践中运行良好:

    1. 对象的分配器在构造后不会改变。
    2. 每个可识别分配器的类型都应将作为构造函数参数接收的分配器传递给所有可识别分配器的成员。

    第二条规则意味着类的构造函数需要照顾它们的所有成员。在成员类型已知的情况下,很容易确定是否需要分配器以及如何构造它。当成员类型在某种形式下是通用的,即它依赖于某种形式的模板参数时,通常不知道是否需要分配器。

    当不清楚成员是否需要接收分配器时,使用bsl 时使用的方法是保存一个包装的成员。更具体地说,成员将持有一个bslalg::ConstructorProxy&lt;T&gt;,它将静态确定T支持构造函数采用分配器并适当地传递分配器。

    【讨论】:

    • 在这里使用std::scoped_allocator_adaptor 有意义吗?
    • @legends2k:这很有可能。但是,我没有使用标准容器的分配器,所以我不知道。
    • @legends2k 对于std::scoped-allocator_adaptorstd::uses_allocator&lt;T,A&gt; 应该有很多(部分)专业化。
    猜你喜欢
    • 2016-05-08
    • 2023-01-22
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 2012-07-21
    • 2012-12-26
    • 1970-01-01
    • 2015-04-06
    相关资源
    最近更新 更多