最終更新日時(UTC):
が更新

履歴 編集

function template
<memory>

std::uses_allocator_construction_args(C++20)

template<class T, class Alloc, class... Args>
  auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) -> see below;       // (1)

template<class T, class Alloc, class Tuple1, class Tuple2>
  auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
                                        Tuple1&& x, Tuple2&& y) -> see below;                   // (2)

template<class T, class Alloc>
  auto uses_allocator_construction_args(const Alloc& alloc) -> see below;                       // (3)

template<class T, class Alloc, class U, class V>
  auto uses_allocator_construction_args(const Alloc& alloc, U&& u, V&& v) -> see below;         // (4)

template<class T, class Alloc, class U, class V>
  auto uses_allocator_construction_args(const Alloc& alloc, const pair<U, V>& pr) -> see below; // (5)

template<class T, class Alloc, class U, class V>
  auto uses_allocator_construction_args(const Alloc& alloc, pair<U, V>&& pr) -> see below;      // (6)

概要

Alloc 型のアロケータオブジェクト alloc を使用した T 型オブジェクトの uses-allocator 構築のために必要なコンストラクタ引数を、tuple 型にして返す。 また、Tpair だった場合は、それぞれの要素に対して uses-allocator 構築するために必要なコンストラクタ引数を、tuple 型にして返す。

構築対象の型 T は関数引数からは推論できないため、明示的に指定する必要がある。

テンプレートパラメータ制約

  • (1) : Tpair の特殊化ではない場合のみオーバーロード解決に参加する
  • (2)~(6) : Tpair の特殊化である場合のみオーバーロード解決に参加する

戻り値

備考

  • 本関数は、uses-allocator 構築をサポートするために C++20 で導入された。
    本関数を用いることで、uses-allocator 構築、特に pair に対する特殊な uses-allocator 構築を容易にサポートすることが可能となる。
    ただし、実際には構築まで実施する make_obj_using_allocatoruninitialized_construct_using_allocator が存在するため、これらの関数を直接呼び出す機会はあまり多くはないだろう。
  • 上記 (1) を見ればわかる通り、uses-allocator 構築は、その名前に反して必ずしもアロケータオブジェクトを使うとは限らないので注意。
    uses_allocator_v<T, Alloc>false の場合、アロケータオブジェクト alloc は無視される)
  • 上記 (2)~(6) を見ればわかる通り、Tpair の場合には再帰的に uses_allocator_construction_args を呼び出しているため、ネストした pair に対しても正しく uses-allocator 構築をサポートできる。

#include <iostream>
#include <utility>
#include <memory>

// 偽アロケータ
struct MyAlloc {};

// アロケータを使用しない偽コンテナ
struct MyContainer0 {
  MyContainer0(int) noexcept {}
};

// 偽アロケータを使用する偽コンテナ(allocator_arg_t 使用)
struct MyContainer1 {
  using allocator_type = MyAlloc;
  MyContainer1(std::allocator_arg_t, const MyAlloc&, int) noexcept {}
};

// 偽アロケータを使用する偽コンテナ(最後の引数)
struct MyContainer2 {
  using allocator_type = MyAlloc;
  MyContainer2(int, const MyAlloc&) noexcept {}
};

// 偽アロケータ用挿入演算子
std::ostream& operator<<(std::ostream& os, const MyAlloc&)
{
  return os << "MyAlloc";
}

// allocator_arg 用挿入演算子
std::ostream& operator<<(std::ostream& os, const std::allocator_arg_t&)
{
  return os << "allocator_arg_t";
}

// piecewise_construct 用挿入演算子
std::ostream& operator<<(std::ostream& os, const std::piecewise_construct_t&)
{
  return os << "piecewise_construct_t";
}

// tuple 用挿入演算子
template <typename... Ts>
std::ostream& operator<<(std::ostream& os, const std::tuple<Ts...>& t)
{
  os << "tuple(";
  std::apply([&os](const auto&... args) {
    ((os << args << ", "), ...);
  }, t);
  return os << ')';
}

int main()
{
  auto a0 = std::uses_allocator_construction_args<MyContainer0>(MyAlloc{}, 0);
  std::cout << a0 << '\n';
  auto a1 = std::uses_allocator_construction_args<MyContainer1>(MyAlloc{}, 1);
  std::cout << a1 << '\n';
  auto a2 = std::uses_allocator_construction_args<MyContainer2>(MyAlloc{}, 2);
  std::cout << a2 << '\n';
  auto a3 = std::uses_allocator_construction_args<std::pair<MyContainer1, MyContainer2>>(MyAlloc{}, 3, 4);
  std::cout << a3 << '\n';
}

出力

tuple(0, )
tuple(allocator_arg_t, MyAlloc, 1, )
tuple(2, MyAlloc, )
tuple(piecewise_construct_t, tuple(allocator_arg_t, MyAlloc, 3, ), tuple(4, MyAlloc, ), )

バージョン

言語

  • C++20

処理系

関連項目

参照