функции uninitialized_X, которые используют конструктор распределителя? - PullRequest
0 голосов
/ 08 февраля 2019

Существует ли версия uninitialized_value_construct, которая использует распределитель для создания элемента на месте вместо размещения new?

Это нижепрототип реализации uninitialized_value_construct;однако я ищу тот, где передается распределитель, чтобы я мог использовать строку alloc.construct(std::addressof(*current)) вместо ::new (std::addressof(*current)).

template<class ForwardIt>
void uninitialized_value_construct(ForwardIt first, ForwardIt last)
{
    using Value = typename std::iterator_traits<ForwardIt>::value_type;
    ForwardIt current = first;
    try {
        for (; current != last; ++current) {
            ::new (static_cast<void*>(std::addressof(*current))) Value();
        }
    } catch (...) {
        std::destroy(first, current);
        throw;
    }
}

В C ++ 20 есть uninitialized_construct_using_allocator но неясно, для чего он нужен или как его использовать.


РЕДАКТИРОВАТЬ: После разговора с @NicolBolas я в итоге реализовал эту пару функций (которые яжелание было в std::).Для моих нужд (и без потери общности я сделаю это для других uninitialized_X функций.

template<class Alloc, class ForwardIt, class Size, class AT = typename std::allocator_traits<Alloc>>
ForwardIt uninitialized_value_construct_n(Alloc& a, ForwardIt first, Size n){
    using T = typename std::iterator_traits<ForwardIt>::value_type;
    ForwardIt current = first;
    try{
        for(; n > 0; (void) ++current, --n) 
            AT::construct(a, std::addressof(*current), T());
//          ::new (static_cast<void*>(std::addressof(*current))) T();
        return current;
    }catch(...){destroy(a, first, current); throw;}
}
template<class Alloc, class ForwardIt, typename AT = typename std::allocator_traits<Alloc> >
void destroy(Alloc& a, ForwardIt first, ForwardIt last){
    for(; first != last; ++first) 
        AT::destroy(a, std::addressof(*first));
    //  destroy_at(std::addressof(*first));
}

1 Ответ

0 голосов
/ 08 февраля 2019

К сожалению, нет никакой ранжированной версии uninitialized_construct, которая принимает распределитель.

Что касается того, для чего uninitialized_construct_using_allocator, то он создает отдельный объект данного типа с заданными аргументами через распределитель,Это может показаться тривиальным (std::allocator_traits<Alloc>::construct(t, alloc, std::forward<Args>(args)...)), но делает это так, что распределитель будет правильно распространяться на scoped_allocator с, используемых этим T.Для этого требуется набор техник, которые не очень хорошо известны и не так легко понять, поэтому для этого есть специальная функция.

...