问题描述
假设我正在编写一个库,并且我希望允许用户提供他们自己的分配器实例,以便他们可以随心所欲地打包内存。有哪些方法可以在 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);
}