Spec-Zone.ru › C++

std::scoped_allocator_adaptor<OuterAlloc,InnerAlloc...>::construct

Определено в заголовке <scoped_allocator>
template< class T, class... Args >
void construct( T* p, Args&&... args );
(1)
template< class T1, class T2, class... Args1, class... Args2 >
void construct( std::pair<T1, T2>* p,
                std::piecewise_construct_t,
                std::tuple<Args1...> x,
                std::tuple<Args2...> y );
(2) (до C++20)
template< class T1, class T2 >
void construct( std::pair<T1, T2>* p );
(3) (до C++20)
template< class T1, class T2, class U, class V >
void construct( std::pair<T1, T2>* p, U&& x, V&& y );
(4) (до C++20)
template< class T1, class T2, class U, class V >
void construct( std::pair<T1, T2>* p, const std::pair<U, V>& xy );
(5) (до C++20)
template< class T1, class T2, class U, class V >
void construct( std::pair<T1, T2>* p, std::pair<U, V>&& xy );
(6) (до C++20)
template< class T1, class T2, class NonPair >
void construct( std::pair<T1, T2>* p, NonPair&& non_pair );
(7) (до C++20)

Создаёт объект в выделенной, но не инициализированной памяти, на которую указывает p, используя OuterAllocator и предоставленные аргументы конструктора. Если объект имеет тип, который сам использует аллокаторы, или если это std::pair, InnerAllocator передаётся построенному объекту.

Сначала извлекается внешний аллокатор OUTERMOST, вызывая this->outer_allocator(), а затем вызывается функция-член outer_allocator() рекурсивно над результатом этого вызова, пока не будет достигнут аллокатор, у которого нет такой функции-члена.

Определим OUTERMOST_ALLOC_TRAITS(x) как std::allocator_traits<std::remove_reference_t<decltype(OUTERMOST(x))>>

1) Создаёт объект заданного типа T с помощью строительства с использованием аллокатора в неинициализированном месте памяти, указанном p, используя OUTERMOST в качестве аллокатора. После корректировки в соответствии с соглашением о построении с использованием аллокатора, ожидаемым конструктором T, вызывается OUTERMOST_ALLOC_TRAITS(*this)::construct.
Эта перегрузка участвует в разрешении перегрузки только если U не является специализацией std::pair. (до C++20)
Эквивалентно
std::apply(

[p, this](auto&&... newargs)
{
OUTERMOST_ALLOC_TRAITS(*this)::construct(
OUTERMOST(*this), p, std::forward<decltype(newargs)>(newargs)...);
},
std::uses_allocator_construction_args(
inner_allocator(),
std::forward<Args>(args)...
)
);

(с C++20)
2) Сначала, если либо T1 либо T2 используют аллокатор, модифицирует кортежи x и y для включения соответствующего внутреннего аллокатора, что приводит к двум новым кортежам xprime и yprime, согласно трём правилам: 2a) если T1 не использует аллокатор
(std::uses_allocator<T1, inner_allocator_type>::value == false), то xprime равно std::tuple<Args1&&...>(std::move(x)). (Также требуется, что std::is_constructible<T1, Args1...>::value == true). 2b) если T1 использует аллокатор (std::uses_allocator<T1, inner_allocator_type>::value == true), и его конструктор принимает тег аллокатора

std::is_constructible<T1, std::allocator_arg_t,
inner_allocator_type&, Args1...>::value == true
,
то xprime равно
std::tuple_cat(std::tuple<std::allocator_arg_t, inner_allocator_type&>(
std::allocator_arg, inner_allocator()
),
std::tuple<Args1&&...>(std::move(x)))

2c) если T1 использует аллокатор (std::uses_allocator<T1, inner_allocator_type>::value == true), и его конструктор принимает аллокатор в качестве последнего аргумента

std::is_constructible<T1, Args1..., inner_allocator_type&>::value == true,
то xprime равно
std::tuple_cat(std::tuple<Args1&&...>(std::move(x)),
std::tuple<inner_allocator_type&>(inner_allocator()))
.

Аналогичные правила применяются к T2 и замене y на yprime. После построения xprime и yprime строит пару p в выделенной памяти, вызвав
std::allocator_traits<O>::construct(OUTERMOST,
p,
std::piecewise_construct,
std::move(xprime),
std::move(yprime));
3) Эквивалентно

construct(p, std::piecewise_construct, std::tuple<>(), std::tuple<>()), т.е. передаёт внутренний аллокатор в члены пары, если они его принимают.

4) Эквивалентно
construct(p, std::piecewise_construct, std::forward_as_tuple(std::forward<U>(x)),
std::forward_as_tuple(std::forward<V>(y)))
5) Эквивалентно
construct(p, std::piecewise_construct, std::forward_as_tuple(xy.first),
std::forward_as_tuple(xy.second))
6) Эквивалентно
construct(p, std::piecewise_construct,
std::forward_as_tuple(std::forward<U>(xy.first)),
std::forward_as_tuple(std::forward<V>(xy.second)))
7) Эта перегрузка участвует в разрешении перегрузки только если предоставлена функция-шаблон только для демонстрации

template<class A, class B>
void /*deduce-as-pair*/(const std::pair<A, B>&);
,
/*deduce-as-pair*/(non_pair) некорректна, когда рассматривается как неоцениваемый операнд.
Эквивалентно construct<T1, T2, T1, T2>(p, std::forward<NonPair>(non_pair));.

(до C++20)

Параметры

p - указатель на выделенную, но не инициализированную память
args... - аргументы конструктора для передачи конструктору T
x - аргументы конструктора для передачи конструктору T1
y - аргументы конструктора для передачи конструктору T2
xy - пара, члены которой являются аргументами конструктора для T1 и T2
non_pair - аргумент, не являющийся парой, для преобразования в pair для дальнейшего построения

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

(нет)

Примечания

Эта функция вызывается (через std::allocator_traits) любым объектом, использующим аллокатор, таким как std::vector, которому был передан std::scoped_allocator_adaptor в качестве используемого аллокатора. Так как inner_allocator сам является экземпляром std::scoped_allocator_adaptor, эта функция также будет вызываться, когда объекты, построенные с помощью этой функции, начинают строить свои собственные члены.

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

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

DR Применено к Поведение, как опубликовано Правильное поведение
LWG 2975 C++11 первая перегрузка ошибочно используется для построения пар в некоторых случаях ограничено, чтобы не принимать пары
P0475R1 C++11 строительство пар по частям может копировать аргументы преобразовано в кортежи ссылок, чтобы избежать копирования
LWG 3525 C++11 нет перегрузки, которая могла бы обработать типы, не являющиеся парами, преобразуемыми в pair добавлена перегрузка для реконструкции

См. также

construct
[статическая]
строит объект в выделенной памяти
(функция-шаблон)
construct
(до C++20)
строит объект в выделенной памяти
(общедоступный член-функция std::allocator<T> )

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

Spec-Zone.ru

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