Spec-Zone.ru › C++

std::uses_allocator_construction_args

Определено в заголовочном файле <memory>
T не является специализацией std::pair
template< class T, class Alloc, class... Args >
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
    Args&&... args ) noexcept;
(1) (с C++20)
T является специализацией std::pair
template< class T, class Alloc, class Tuple1, class Tuple2 >
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
    std::piecewise_construct_t, Tuple1&& x, Tuple2&& y ) noexcept;
(2) (с C++20)
template< class T, class Alloc >
constexpr auto uses_allocator_construction_args( const Alloc& alloc ) noexcept;
(3) (с C++20)
template< class T, class Alloc, class U, class V >
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
    U&& u, V&& v ) noexcept;
(4) (с C++20)
template< class T, class Alloc, class U, class V >
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
    std::pair<U, V>& pr ) noexcept;
(5) (с C++23)
template< class T, class Alloc, class U, class V >
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
    const std::pair<U, V>& pr ) noexcept;
(6) (с C++20)
template< class T, class Alloc, class U, class V >
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
    std::pair<U, V>&& pr ) noexcept;
(7) (с C++20)
template< class T, class Alloc, class U, class V >
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
    const std::pair<U, V>&& pr ) noexcept;
(8) (с C++23)
template< class T, class Alloc, class NonPair >
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
    NonPair&& non_pair ) noexcept;
(9) (с C++20)

Подготавливает список аргументов, необходимых для создания объекта заданного типа T с помощью конструирования с использованием аллокатора.

1) Этот перегруз участвует в разрешении перегрузки только если T не является специализацией std::pair. Возвращает std::tuple, определяемый следующим образом:
  • Если std::uses_allocator_v<T, Alloc> — false и std::is_constructible_v<T, Args...> — true, возвращает std::forward_as_tuple(std::forward<Args>(args)...).
  • В противном случае, если std::uses_allocator_v<T, Alloc> — true и std::is_constructible_v<T, std::allocator_arg_t, const Alloc&, Args...> — true, возвращает
    std::tuple<std::allocator_arg_t, const Alloc&, Args&&...>(std::allocator_arg, alloc,
    std::forward<Args>(args)...)
    .
  • В противном случае, если std::uses_allocator_v<T, Alloc> — true и std::is_constructible_v<T, Args..., const Alloc&> — true, возвращает std::forward_as_tuple(std::forward<Args>(args)..., alloc).
  • В противном случае, программа некорректна.
2) Этот перегруз участвует в разрешении перегрузки только если T является специализацией std::pair. Для T, который является std::pair<T1, T2>, эквивалентно
return std::make_tuple(std::piecewise_construct,
    std::apply([&alloc](auto&&... args1)
        {
            return std::uses_allocator_construction_args<T1>(alloc,
                       std::forward<decltype(args1)>(args1)...);
        }, std::forward<Tuple1>(x)
    ),
    std::apply([&alloc](auto&&... args2)
        {
            return std::uses_allocator_construction_args<T2>(alloc,
                       std::forward<decltype(args2)>(args2)...);
        }, std::forward<Tuple2>(y)
    )
);
3) Этот перегруз участвует в разрешении перегрузки только если T является специализацией std::pair. Эквивалентно
return std::uses_allocator_construction_args<T>(alloc,
    std::piecewise_construct, std::tuple<>{}, std::tuple<>{}
);
4) Этот перегруз участвует в разрешении перегрузки только если T является специализацией std::pair. Эквивалентно
return std::uses_allocator_construction_args<T>(alloc,
    std::piecewise_construct,
    std::forward_as_tuple(std::forward<U>(u)),
    std::forward_as_tuple(std::forward<V>(v))
);
5,6) Этот перегруз участвует в разрешении перегрузки только если T является специализацией std::pair. Эквивалентно
return std::uses_allocator_construction_args<T>(alloc,
    std::piecewise_construct,
    std::forward_as_tuple(pr.first),
    std::forward_as_tuple(pr.second)
);
7,8) Этот перегруз участвует в разрешении перегрузки только если T является специализацией std::pair. Эквивалентно
return std::uses_allocator_construction_args<T>(alloc,
    std::piecewise_construct,
    std::forward_as_tuple(std::get<0>(std::move(pr))),
    std::forward_as_tuple(std::get<1>(std::move(pr)))
);
9) Этот перегруз участвует в разрешении перегрузки только если T является специализацией std::pair, и с учётом шаблона функции только для демонстрации
template<class A, class B>
void /*deduce-as-pair*/(const std::pair<A, B>&);

, /*deduce-as-pair*/(non_pair) некорректен, если рассматривается как неоцениваемый операнд.
Пусть демонстрационный класс pair-constructor определяется как

class /*pair-constructor*/
{
    const Alloc& alloc_; // exposition only
    NonPair&     u_;     // exposition only
 
    constexpr reconstruct(const std::remove_cv<T>& p) const // exposition only
    {
        return std::make_obj_using_allocator<std::remove_cv<T>>(alloc_, p);
    }
 
    constexpr reconstruct(std::remove_cv<T>&& p) const // exposition only
    {
        return std::make_obj_using_allocator<std::remove_cv<T>>(alloc_, std::move(p));
    }
 
public:
    constexpr operator std::remove_cv<T>() const
    {
        return reconstruct(std::forward<NonPair>(u_));
    }
};
Этот перегруз эквивалентен return std::make_tuple(pair_construction);, где pair_construction — значение типа pair-constructor, чьи члены alloc_ и u_ равны alloc и non_pair соответственно.

Параметры

alloc - используемый аллокатор
args - аргументы для передачи в конструктор T
x - кортеж аргументов для передачи в конструкторы T's first
y - кортеж аргументов для передачи в конструкторы T's second
u - одиночный аргумент для передачи в конструктор T's first
v - одиночный аргумент для передачи в конструктор T's second
pr - пара, чьё значение first будет передано в конструктор T's first и значение second будет передано в конструктор T's second
non_pair - одиночный аргумент для преобразования в std::pair для дальнейшего конструирования

Возвращаемое значение

Список аргументов, подходящих для передачи в конструктор T.

Примечания

Перегрузки (2-9) обеспечивают распространение аллокатора в std::pair, что не поддерживает соглашения о вызовах с ведущим или хвостовым аллокатором (в отличие, например, от std::tuple, который использует соглашение с ведущим аллокатором).

При использовании в конструировании с использованием аллокатора, функция преобразования pair-constructor сначала преобразует предоставленный аргумент в std::pair, а затем строит результат из этого std::pair с помощью конструирования с использованием аллокатора.

Пример

Отчёты об ошибках

Следующие исправляющие ошибки отчёты были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применён к Поведение, как опубликовано Правильное поведение
LWG 3525 C++20 нет перегрузки, которая могла бы обработать типы, не являющиеся pair и преобразуемые в pair добавлен перегруз для реконструкции

См. также

uses_allocator
(C++11)
проверяет, поддерживает ли указанный тип конструирование с использованием аллокатора
(шаблон класса)
make_obj_using_allocator
(C++20)
создаёт объект заданного типа с помощью конструирования с использованием аллокатора
(шаблон функции)
uninitialized_construct_using_allocator
(C++20)
создаёт объект заданного типа по указанному адресу памяти с помощью конструирования с использованием аллокатора
(шаблон функции)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/memory/uses_allocator_construction_args

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API