将内存池分配器耦合到托管已分配实例的各种内存池
Coupling memory pool allocator to various memory pools hosting the allocated instances
存在无状态内存池分配器class:
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()
成员函数的特殊化,其目的是 return 定义类型的特定内存池,其中应分配 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()
在其他编译单元中的使用(auto
占位符的类型不能被推断为get_pool()
函数模板专业化不可用)
There fore I would like to somehow get rid of auto
as return type
of get_pool()
.
我面临的问题主要是 memory_pool
的大小,这对分配器本身是未知的。无论如何,memory_pool 也是我的实现,所以我可以 du 任何需要的采用(例如进一步的 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;
}
...
};
这是我使用的解决方案 - 实现特征 class,其中包含有关池大小的信息:
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;
};
对于任何特定类型,都应具有特征 class:
// 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;
}
存在无状态内存池分配器class:
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()
成员函数的特殊化,其目的是 return 定义类型的特定内存池,其中应分配 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()
在其他编译单元中的使用(auto
占位符的类型不能被推断为get_pool()
函数模板专业化不可用)
There fore I would like to somehow get rid of
auto
as return type ofget_pool()
.
我面临的问题主要是 memory_pool
的大小,这对分配器本身是未知的。无论如何,memory_pool 也是我的实现,所以我可以 du 任何需要的采用(例如进一步的 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;
}
...
};
这是我使用的解决方案 - 实现特征 class,其中包含有关池大小的信息:
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;
};
对于任何特定类型,都应具有特征 class:
// 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;
}