Я реализую контейнер, который по примеру std::vector
имеет приватный unitialize_construct
.
template<class... Args>
auto uninitialized_construct(Args&&... args){
auto cur = data_;
for(size_type n = this->num_elements(); n > 0; --n, ++cur)
alloc_traits::construct(allocator_, std::addressof(*cur), std::forward<Args>(args)...);
}catch(...){destroy(cur); throw;}
}
Мне кажется, что для общих целей программирования было бы лучше использовать алгоритм, а не простой цикл. Оказывается, в стандарте есть std::unitialized_fill_n
, что делает размещение новым, и по сути это очень похоже.
https://en.cppreference.com/w/cpp/memory/uninitialized_fill_n
Однако существует большая проблема, std::uninitialized_fill_n
не имеет аргумента с вариацией, и поэтому я не могу переслать args...
.
Почему это так? Есть ли другой вариант uninitialized_fill_n, который может пересылать аргументы конструкции?
Если нет, я должен позвонить unitialized_fill_n(data, size, value_type(std::forward<Args>(args)...))
?
Повторюсь, я ожидал, что смогу сказать unitialized_fill_n(data, size, std::forward<Args>(args)...)
.
РЕДАКТИРОВАТЬ: Из того, что я понимаю из комментария @ Deduplicator, у меня была ошибка в исходном коде, потому что я много раз переходил от аргументов к аргументам.
template<class... Args>
auto uninitialized_construct(Args&&... args){
typename array::element_ptr cur = this->data();
for(size_type n = this->num_elements(); n > 0; --n, ++cur)
alloc_traits::construct(allocator_, std::addressof(*cur), args...);
}catch(...){destroy(cur); throw;}
}
Как только я внесу это изменение, цикл можно заменить стандартной функцией:
template<class... Args>
auto uninitialized_construct(Args&&... args){
std::unitialized_fill_n(data_, n, T(args...)); // or should I construct a copy first?
}