我们如何允许用户提供一个内存分配器实例来请求内存?

问题描述

假设我正在编写一个库,并且我希望允许用户提供他们自己的分配器实例,以便他们可以随心所欲地打包内存。有哪些方法可以在 C++17 中专门实现这一点?

例如,如果我使用 new int[5] 之类的东西,那将不会使用用户自定义分配器。允许自定义分配器时该语句的等价物是什么?

解决方法

任何需要分配的自由函数都需要成为函数模板。

void foo(int arg); // has new int[N] somewhere

变成

template <typename Allocator = std::allocator<int>>
void foo(int arg,Allocator alloc = {}); // has alloc.allocate(N) somewhere

任何其成员函数分配的类都需要成为类模板。

class bar {
public:
    bar() = default;
    void baz() // has new double[N] somewhere
};

变成

template <typename Allocator = std::allocator<double>>
class bar {
public:
    bar(Allocator alloc = {}) : alloc(alloc) {}
    void baz() // has alloc.allocate(N) somewhere
private:
    Allocator alloc;
};

如果您需要分配多种类型的值,请确定最自然的需要,并使用 typename std::allocator_traits<Allocator>::template rebind_alloc<OtherType> 获取 OtherType 的分配器类型。

任何使用这些函数或类的任何东西都需要通过分配器传递给它。

您很可能会使用标准库类型。您也应该允许调用者在那里指定分配器。

namespace rrohak_lib {

    class SomeValue { /*...*/ };

    template <typename Allocator = std::allocator<SomeValue>>
    void frobnicate(std::vector<SomeValue,Allocator> & vec);
}