Как обезопасить мой uninitialised_allocator?
Исходя изэтот вопросЯ хочу использоватьunitialised_allocator
с, скажем,std::vector
чтобы избежать инициализации элементов по умолчанию при создании (илиresize()
изstd::vector
(смотрите такжеВот для случая использования). Мой текущий дизайн выглядит так:
// based on a design by Jared Hoberock
template
struct uninitialised_allocator : base_allocator::template rebind::other
{
// added by Walter Q: IS THIS THE CORRECT CONDITION?
static_assert(std::is_trivially_default_constructible::value,
"value type must be default constructible");
// added by Walter Q: IS THIS THE CORRECT CONDITION?
static_assert(std::is_trivially_destructible::value,
"value type must be default destructible");
using base_t = typename base_allocator::template rebind::other;
template
struct rebind
{
typedef uninitialised_allocator other;
};
typename base_t::pointer allocate(typename base_t::size_type n)
{
return base_t::allocate(n);
}
// catch default construction
void construct(T*)
{
// no-op
}
// forward everything else with at least one argument to the base
template
void construct(T* p, Arg1 &&arg1, Args&&... args)default_
{
base_t::construct(p, std::forward(arg1), std::forward(args)...);
}
};
Тогдаunitialised_vector
шаблон может быть определен так:
template
using uninitialised_vector =
std::vector;
Однако, как указано в моих комментариях, ям не уверен на 100%Каковы соответствующие условия в?static_assert()
(Кстати, вместо этого можно рассмотреть SFINAE - любые полезные комментарии по этому поводу приветствуются)
Очевидно, что следует избегать катастрофы, которая может возникнуть в результате попытки нетривиального уничтожения неинициализированного объекта. Рассматривать
unitialised_vector< std::vector > x(10); // dangerous.
Было предложено (комментарий Евгения Панасюка), что я утверждаю тривиальную конструктивность, но это, похоже, не улавливает вышеупомянутый сценарий катастрофы. Я просто попытался проверить, что говорит Clangstd::is_trivially_default_constructible
(или жеstd::is_trivially_destructible
) но все, что я получил, это крах clang 3.2 ...
Другой, более продвинутый вариант - создать распределитель, который исключает конструкцию по умолчанию только для объектов, для которых это было бы безопасно.