Я пытаюсь реализовать класс, который следует в памяти массивом некоторого произвольного типа:
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
вернет память, подходящую для любого типа объекта? Если да, могу ли я в противном случае просто использовать распределитель какого-либо типа char? Если нет, есть ли у меня какие-либо альтернативы или эта задача невозможна для распределителей в целом? (В худшем случае, я полагаю, я мог бы наложить указатели на uintptr_t
и выровнять их вручную, но мне интересно, есть ли лучший способ.)