◐ Shell
clean mode source ↗

std::uses_allocator_construction_args — cppreference.com

Материал из cppreference.com

<tbody> </tbody>

Определено в заголовочном файле <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 /*выводится-как-pair*/(const std::pair<A, B>&);

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

class /*pair-constructor*/
{
    const Alloc& alloc_; // только для пояснения
    NonPair&     u_;     // только для пояснения

    constexpr reconstruct(const std::remove_cv<T>& p) const // только для пояснения
    {
        return std::make_obj_using_allocator<std::remove_cv<T>>(alloc_, p);
    }

    constexpr reconstruct(std::remove_cv<T>&& p) const // только для пояснения
    {
        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 элемента данных first
y кортеж аргументов для передачи конструкторам T элемента данных second
u единственный аргумент для передачи конструктору T элемента данных first
v единственный аргумент для передачи конструктору T элемента данных second
pr pair, чей элемент данных first, который будет передан конструктору T как элемент данных first и элемент данных second, который будет передан конструктору T как элемент данных second
non_pair единственный аргумент для преобразования в std::pair для дальнейшего построения

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

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

Примечание

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

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

Пример

Отчёты о дефектах

Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:

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

Смотрите также