我正在尝试实现我的自定义向量。在某些情况下,我决定将容量放在真实数据的前面,通过移动指针来访问容量。 假设
sizeof(capacity) == 4
而sizeof(value_type) == 512
,使用allocator<T>
无疑会造成内存碎片,这可能是不可接受的。
因此,我不能使用 allocator<T>::allocate
来分配整个块内存。
但是,我可以同时持有两个分配器(allocator<T>
和 rebind_alloc<byte>
),然后通过 rebind_alloc<byte>
分配内存并通过 allocator<T>
构造值。我不知道它是否符合标准要求。或者,还有什么好主意吗?
为一个容器保留两个分配器可能很难维护,所以根据我的问题,我需要的是一个状态分配器。 标准库中已经有了现成的范式,叫做
std::scoped_allocator_adapater
.
类模板是一个分配器,可用于多级容器(地图元组列表列表的向量等)。它使用一个外部分配器类型std::scoped_allocator_adaptor
和零个或多个内部分配器类型OuterAlloc
进行实例化。直接用InnerAlloc...
构造的容器使用scoped_allocator_adaptor
分配其元素,但如果元素本身是容器,则它使用第一个内部分配器。该容器的元素,如果它们本身是容器,则使用第二个内部分配器等。如果容器的级别多于内部分配器,则最后一个内部分配器将重新用于所有进一步嵌套的容器。OuterAlloc
那个
std::scoped_allocator_adapter
是我这里需要的。所以,我这样实现我的分配器:
template <class AllocByte, class AllocTy>
class MyAlloc : AllocTy, AllocByte {
using alty_traits = std::allocator_traits<AllocTy>;
using albyte_traits = std::allocator_traits<AllocByte>;
public:
using alty_type = AllocTy;
using albyte_type = AllocByte;
// other functions and type alias
albyte_type& byte_allocator() noexcept { return static_cast<AllocByte&>(*this); }
const albyte_type& byte_allocator() const noexcept { return static_cast<const AllocByte&>(*this); }
alty_type& value_allocator() noexcept { return static_cast<AllocTy&>(*this); }
const alty_type& value_allocator() const noexcept { return static_cast<const AllocTy&>(*this); }
pointer allocate(size_type n) { return albyte_traits::allocate(byte_allocator(), n); }
void deallocate(pointer ptr, size_type n) { return albyte_traits::deallocate(byte_allocator(), ptr, n); }
size_type max_size() const { return albyte_traits::max_size(byte_allocator()); }
template <class _Ty, class... _Args>
void construct(_Ty* ptr, _Args&&... args) {
alty_traits::construct(value_allocator(), ptr, std::forward<_Args>(args)...);
}
template <class _Ty>
void destroy(_Ty* ptr) {
alty_traits::destroy(value_allocator(), ptr);
}
};