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

履歴 編集

class template
<memory>

std::polymorphic(C++26)

namespace std {
  template <class T, class Allocator = allocator<T>>
  class polymorphic;

  namespace pmr {
    template <class T>
    using polymorphic = std::polymorphic<T, polymorphic_allocator<T>>;
  }
}

概要

std::polymorphicクラスは、動的確保したオブジェクトに値の意味論をもたせつつ、Tから派生した任意の型のオブジェクトを多態的に保持できる型である。

std::indirectクラスが単一の型Tのオブジェクトを保持するのに対し、std::polymorphic<T>クラスはTを基底とする派生型のオブジェクトを保持できる。値型としての性質はstd::indirectクラスと共通している:

  • ディープコピー: std::polymorphic<T>クラスのオブジェクトをコピーすると、実際に保持している派生型のオブジェクトが、その派生型のコピーコンストラクタによって複製される(型消去をとおした仮想ディスパッチが用いられる)
  • constの伝播: constなアクセス経路から所有オブジェクトにアクセスすると、所有オブジェクトにもconstが伝播する
  • 不完全型のサポート: テンプレートパラメータT不完全型でもよい

これらの性質によって、std::polymorphicクラスは多態的な性質をもつクラスのメンバ変数として適しており、コンパイラによる特殊メンバ関数の自動生成と協調して動作する。

所有オブジェクトを持たない状態を「無効値状態 (valueless state)」と呼ぶ。std::polymorphicクラスが無効値状態になるのは、ムーブ後に空となった場合のみである。無効値状態のオブジェクトに対するoperator*operator->の呼び出しは未定義動作を引き起こす。無効値状態かどうかはvalueless_after_move()で判定できる。

保持する型の集合が既知である場合は、std::variantindirect<std::variant<...>>の使用を検討するとよい。

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

  • AllocatorはCpp17Allocator要件を満たすこと。
  • allocator_traits<Allocator>::value_typeTと同じ型であること

適格要件

メンバ関数

構築・破棄

名前 説明 対応バージョン
(constructor) コンストラクタ C++26
(destructor) デストラクタ C++26
operator= 代入演算子 C++26

値へのアクセス

名前 説明 対応バージョン
operator* 所有するオブジェクトへの参照を取得する C++26
operator-> 所有するオブジェクトのメンバへアクセスする C++26
valueless_after_move 無効値状態かどうかを判定する C++26

その他

名前 説明 対応バージョン
get_allocator アロケータを取得する C++26
swap 他のpolymorphicオブジェクトと値を交換する C++26

メンバ型

名前 定義 対応バージョン
value_type T C++26
allocator_type Allocator C++26
pointer allocator_traits<Allocator>::pointer C++26
const_pointer allocator_traits<Allocator>::const_pointer C++26

非メンバ(Hidden friends)関数

名前 説明 対応バージョン
swap 2つのpolymorphicオブジェクトを交換する C++26

#include <cassert>
#include <memory>

struct Shape {
  virtual ~Shape() = default;
  virtual int area() const = 0;
};

struct Square : Shape {
  int side;
  Square(int s) : side(s) {}
  int area() const override { return side * side; }
};

int main()
{
  // Shapeから派生したSquareを、値の意味論で多態的に保持する
  std::polymorphic<Shape> a{std::in_place_type<Square>, 3};
  assert(a->area() == 9);

  // コピーは派生型(Square)のディープコピー
  std::polymorphic<Shape> b = a;
  assert(b->area() == 9);
}

出力

バージョン

言語

  • C++26

処理系

関連項目

  • std::indirect 単一の型を保持する値型
  • std::variant 既知の型集合から1つを保持する型
  • std::unique_ptr 多態的な所有権をもつが参照の意味論をもつスマートポインタ

参照