我正在尝试实现一个类,它在内存中由某种任意类型的数组跟随:
template<class T>
class Buf
{
size_t n;
int refs;
explicit Buf(size_t n) : n(n) { }
// other declarations are here as appropriate
// Followed in memory by:
// T items[n];
};
这很容易使用
operator new
实现:template<class T>
Buf<T> *make_buf(size_t n)
{
// Assume the caller will take care of constructing the array elements
return new(operator new(sizeof(Buf<T>) + sizeof(T) * n)) Buf<T>(n);
}
template<class T>
void free_buf(Buf<T> *p)
{
// Assume the caller has taken care of destroying the array elements
p->~Buf<T>();
return operator delete(p);
}
template<class T>
T *get_buf_array(Buf<T> *p)
{
return reinterpret_cast<T *>(reinterpret_cast<char *>(p) + sizeof(Buf<T>));
}
现在,我该如何使用符合标准的SomeAllocator
分配器来实现呢?
SomeAllocator::rebind<char>::other::allocate
保证返回适合任何类型对象的内存空间吗?如果是,那么只使用某个字符类型的分配器就足够安全了吗?如果不是,是否有其他选择,或者说使用分配器根本无法完成这个任务?(最坏的情况下,我可以将指针强制转换为uintptr_t
并手动对齐,但我想知道是否有更好的方法。)
std::align
... - Kerrek SBBuf<T>
的分配器按照该类型的倍数进行分配,因此我认为这并没有什么用处。当然,您可以进行一些大小计算,但至少您仍需要以某种方式对第一个数组元素的地址进行对齐。 - Kerrek SBBuf
和元素的对齐方式已经处理好了-否则您需要获取它们的最大对齐方式。对于分配器...您可以使用rebind<Aligned_Allocator<std::alignment_of<Buf<T>>>
,其中AlignedAllocator
被专门化,因此<1>
需要对齐1(例如包含一个int8_t
),<2>
需要对齐2等等。 - Tony Delroy