Я хотел бы создать шаблон класса, который принимает тип распределителя (как определено в стандартном разделе 17.6.3.5) в качестве аргумента шаблона. Я вижу, как std::allocator_traits<A>
помогает заполнять любые отсутствующие элементы A
с настройками по умолчанию. Помимо этого, есть ли что-нибудь в стандартной библиотеке или повысить, что поможет правильно использовать распределитель?Использование std :: allocator_traits <A>
В частности:
В честь как
std::allocator_traits<A>::propagate_on_container_copy_assignment
определений типов, я должен проверить эти вещи в специальных функциях членов каждого класса, который имеет элемент типаA
? Или есть какой-то тип обертки, который я мог бы использовать в качестве члена вместо этого, который позаботится об этом?Если я хочу, чтобы суммарный набор уменьшал количество распределений путем хранения дополнительных данных рядом с видимыми пользователем объектами, целесообразно ли переустанавливать распределитель примерно так?
.
template<typename T, typename A>
class MyClass
{
private:
//...
struct storage {
int m_special_data;
T m_obj;
};
typedef typename std::allocator_traits<A>::template rebind_alloc<storage>
storage_alloc;
typedef typename std::allocator_traits<A>::template rebind_traits<storage>
storage_traits;
storage_alloc m_alloc;
static T* alloc(T&& obj)
{
storage_traits::pointer sp = storage_traits::allocate(m_alloc, 1);
sp->m_special_data = 69105;
return ::new(&sp->m_obj) T(std::move(obj));
}
//...
};
Не означает, что любые другие типы, которые не должны использовать 'construct', противоречат предложению' storage_traits :: construct (m_alloc, &sp); ', или это не считается из-за' rebind'? Если я создаю 'хранилище 'и он все еще имеет член типа' T', тогда этот элемент создается вместе с 'storage', а не' construct'. Поэтому мне нужно было бы сделать какой-то «union» или 'static_cast' из' void' trick? – aschepler
@aschepler, +1, хорошо замечен! исправлено сейчас, спасибо –
Что касается вашего второго вопроса, да, вы можете использовать объединение или подходящий размер и подходящий массив 'char'. опыт проще просто гарантировать, что 'storage' содержит только тривиально-конструктивные данные, кроме' T', поэтому вы можете «построить» 'T' и просто присваивать значения другим частям (как правило, просто указателям и/или целым числам). Я отредактирую свой анвве r, чтобы отразить это. –