将内存池分配器耦合到托管所分配实例的各种内存池



有一个无状态内存池分配器类:

template<typename T>
class pool_allocator {
public:
using value_type = T;
using pointer = value_type *;
/* Default constructor */
constexpr pool_allocator( void ) noexcept = default;
/* Converting constructor used for rebinding */
template<typename U>
constexpr pool_allocator( const pool_allocator<U> & ) noexcept {}
[[nodiscard]] pointer allocate( size_t n, [[maybe_unused]] const pointer hint = nullptr ) const noexcept {
return get_pool().allocate( n );
}
void deallocate( pointer ptr, size_t n ) const noexcept {
get_pool().deallocate( ptr, n );
}
private:
/* Must be defined in particular .cpp files */
/* POINT OF INTERREST HERE: */
static auto & get_pool( void ) noexcept;
};

背后的逻辑是get_pool()成员函数的特殊化,该函数旨在返回定义类型的特定内存池,其中应分配T的实例,例如:

class sample { ... };

在.cpp文件中:

memory_pool<sample, 10> sample_storage;  // memory pool capable of holding up to 10 instances of 'sample'

最后是.cpp文件中get_pool((函数模板的特殊化:

template<>
auto & pool_allocator<sample>::get_pool( void ) noexcept {
return sample_storage; // return the memory_pool instance defined above
}

问题是这样的模板专用化仅在.cpp编译单元中可用,并阻止在其他编译单元中使用auto get_pool()(由于get_pool()函数的主体模板专用化不可用,因此无法推断auto占位符的类型(

因此,我想以某种方式取消auto作为返回类型CCD_ 6。

我面临的问题主要是memory_pool的大小,这对分配器本身来说是未知的。不管怎样,memory_pool也是我的实现,所以我可以进行任何需要的采用(例如,进一步的using声明或其他需要的东西(。只是它的一个骨架:

template<typename T, size_t CAPACITY>
class memory_pool {
public:
using element_type = T;
using pointer = element_type *;
constexpr size_t capacity( void ) noexcept {
return CAPACITY;
}
...
};

这是我使用的解决方案-实现traits类,该类保存有关池大小的信息:

template<typename T>
class memory_pool {
public:
using traits = memory_pool_traits<T>;
using element_type = typename traits::element_type;
using pointer = element_type *;
static constexpr size_t capacity { traits::capacity };
...
};

分配器:

template<typename T>
class pool_allocator {
public:
using value_type = T;
using pointer = value_type *;
/* Default constructor */
constexpr pool_allocator( void ) noexcept = default;
/* Converting constructor used for rebinding */
template<typename U>
constexpr pool_allocator( const pool_allocator<U> & ) noexcept {}
[[nodiscard]] pointer allocate( size_t n, [[maybe_unused]] const pointer hint = nullptr ) const noexcept {
return get_pool().allocate( n );
}
void deallocate( pointer ptr, size_t n ) const noexcept {
get_pool().deallocate( ptr, n );
}
private:
static memory_pool<T> & get_pool( void ) noexcept;
};

对于任何特定类型,应具有特征类别:

// Primary template
template<typename T> struct memory_pool_traits;

假设有一个样本,我想为其定义memory_pool:

class sample { ... };

除此之外,各个memory_pool:的设置-特征

template<>
struct memory_pool_traits<sample> {
using element_type = sample;
static constexpr size_t capacity { 10 };
};

.cpp文件中,有池本身的定义和get_pool()函数:

memory_pool<sample> sample_storage;
template<>
memory_pool<sample> & pool_allocator<sample>::get_pool( void ) noexcept {
return sample_storage;
}

最新更新