本文介绍了对类的AllocatorAwareContainer数据成员使用自定义分配器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Given a non-stateless custom allocator A (say, arena allocator, binded to some contiguous memory chunk of runtime-known size) and class S, containing a fileds of AllocatorAwareContainer types:

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

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

I want to use A for a subset (or even for all) AllocatorAwareContainer fields of class S. It is clear, that I should to provide one another template parameter for class S and change types of all the interesting data members correspondingly as follows:

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 ,并且可能存在其他可能的限制)?

What are changes in present constructors and additional constructors (assume A is not DefaultConstructible and any other possible restrictions may holds) should I made?

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

Should I store allocator A in additional field of class S?

对类使用自定义分配器的一般提示是什么?

What is a general tips to use custom allocators for classes?

推荐答案

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

I'm used to using the containers from bsl which are allocator-aware and to creating allocator-aware classes. The primary difference to the standard containers and their allocator use is that bsl uses a pointer to the allocator base class (bslma::Allocator). This approach gets nicely rid of the std::rebind-dance which complicates matters in an area which is already relatively complicated. Otherwise, I think the concepts translate. I don't have experience using allocators with standard library containers.

使用分配器有两个基本规则,它们在实践中很有效:

There are two fundamental rules for the use of allocators which work well in practice:

  1. 对象的分配器一旦构造就不会更改.
  2. 每个知道分配器的类型都应将作为构造函数参数接收的分配器传递给所有知道分配器的成员.

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

The second rule implies that constructors of classes need to take care of all their members. Where the member type is known it is fairly straight forward to determine whether an allocator is needed and how it is to be constructed. When the member type is generic in some form, i.e., it depends on a template argument in some form, it is generally not known whether an allocator is needed.

不清楚成员是否需要接收分配器时,使用 bsl 用于容纳一个包装的成员.更具体地说,成员将持有 bslalg::ConstructorProxy<T> T静态确定的a>支持采用分配器并适当地传递分配器的构造函数.

When it is unclear whether a member needs to receive an allocator the approach used when using bsl is to hold a wrapped member. More specifically, the members would hold a bslalg::ConstructorProxy<T> which would determine statically with T supports constructors taking allocators and appropriate passes an allocator or not.

这篇关于对类的AllocatorAwareContainer数据成员使用自定义分配器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!