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, | (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未満) |
(5) | (C++20未満) | |
(6) | (C++20未満) | |
p
の指す、確保済みだけれども初期化されていない記憶域に、 OuterAllocator および提供されたコンストラクタ引数を使用してオブジェクトを構築します。 そのオブジェクトがそれ自身アロケータを使用する型であれば、または std::pair であれば、その構築されるオブジェクトに InnerAllocator が下げ渡されます。
まず、 this->outer_allocator() を呼び、その後、そのようなメンバ関数を持たないアロケータに達するまで、この呼び出しの結果に対して再帰的に outer_allocator()
メンバ関数を呼ぶことによって、最も外側のアロケータ OUTERMOST
を取得します。
OUTERMOST_ALLOC_TRAITS(x) を std::allocator_traits<std::remove_reference_t<decltype(OUTERMOST(x))>> として定義します。
T
のオブジェクトを構築します。 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 のいずれかがアロケータ対応の場合は、以下の3つのルールに従って、適切な内部アロケータを含むようにタプル x および y を変更し、新しい2つのタプル 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))) | (C++20未満) |
目次 |
[編集]引数
p | - | 確保したけれども初期化されていない記憶域を指すポインタ |
args... | - | T のコンストラクタに渡すコンストラクタ引数 |
x | - | T1 のコンストラクタに渡すコンストラクタ引数 |
y | - | T2 のコンストラクタに渡すコンストラクタ引数 |
xy | - | T1 および T2 のためのコンストラクタ引数である2つのメンバを持つペア |
[編集]戻り値
(なし)
[編集]ノート
この関数は、使用するアロケータとして std::scoped_allocator_adaptor が与えられた、 std::vector などの任意のアロケータ対応オブジェクトによって、 (std::allocator_traits を通して) 呼ばれます。 inner_allocator
はそれ自身 std::scoped_allocator_adaptor の実体化であるため、この関数を通して構築されたアロケータ対応オブジェクトがそのメンバの構築を開始するときもこの関数が呼ばれます。
[編集] 欠陥報告
以下の動作変更欠陥報告は以前に発行された C++ 標準に遡って適用されました。
DR | 適用先 | 発行時の動作 | 正しい動作 |
---|---|---|---|
LWG 2975 | C++11 | first overload is mistakenly used for pair construction in some cases | constrained to not accept pairs |
P0475R1 | C++11 | pair piecewise construction may copy the arguments | transformed to tuples of references to avoid copy |
[編集]関連項目
[静的] | 確保された記憶域にオブジェクトを構築します (関数テンプレート) |
(C++17で非推奨)(C++20で削除) | 確保された記憶域にオブジェクトを構築します ( std::allocator<T> のパブリックメンバ関数) |