std:: variant
|
ヘッダーで定義
<variant>
|
||
|
template
<
class
...
Types
>
class variant ; |
(C++17以降) | |
クラステンプレート
std::variant
は型安全な
union
を表現します。
variant
のインスタンスは、任意の時点でその代替型のいずれかの値を保持するか、エラーの場合には値を保持しません(この状態は達成が困難です。
valueless_by_exception
を参照してください)。
unionと同様に、variantが何らかのオブジェクト型
T
の値を保持する場合、
T
オブジェクトは
variantオブジェクト内にネストされます
。
variantは参照、配列、または型 void を保持することが許可されていません。
variantは同じ型を複数回保持すること、および同じ型の異なるcv修飾バージョンを保持することが許可されています。
共用体の 集約初期化 時の動作と一貫して、デフォルト構築されたvariantはその最初の代替型の値を保持します。ただし、その代替型がデフォルト構築可能でない場合は除きます(その場合、variantもデフォルト構築可能ではありません)。ヘルパークラス std::monostate を使用することで、そのようなvariantをデフォルト構築可能にすることができます。
テンプレート引数なしで
std::variant
の定義をインスタンス化するプログラムはill-formedです。
std
::
variant
<
std::
monostate
>
を代わりに使用できます。
プログラムが
explicit
または
partial
特殊化の
std::variant
を宣言する場合、そのプログラムは診断不要のill-formedとなる。
目次 |
テンプレートパラメータ
| Types | - | このvariantに格納される可能性のある型。すべての型は Destructible 要件を満たさなければならない(特に、配列型と非オブジェクト型は許可されない)。 |
メンバー関数
variant
オブジェクトを構築する
(public member function) |
|
variant
とその保持する値を破棄する
(public member function) |
|
variant
を代入する
(public member function) |
|
オブザーバー |
|
variant
が保持する代替型のゼロベースのインデックスを返す
(public member function) |
|
variant
が無効な状態かどうかをチェックする
(public member function) |
|
モディファイア |
|
variant
内に値をその場で構築する
(public member function) |
|
他の
variant
と交換する
(public member function) |
|
ビジテーション |
|
|
(C++26)
|
variant
が保持する引数で提供されたファンクタを呼び出す
(public member function) |
非メンバー関数
|
(C++17)
|
1つ以上の
variant
が保持する引数で提供されたファンクタを呼び出す
(関数テンプレート) |
|
(C++17)
|
variant
が現在指定された型を保持しているかどうかをチェックする
(関数テンプレート) |
|
(C++17)
|
インデックスまたは型(型が一意の場合)を指定してvariantの値を読み取り、エラー時には例外をスローする
(関数テンプレート) |
|
(C++17)
|
インデックスまたは型(一意の場合)を指定して、指し示される
variant
の値へのポインタを取得し、エラー時にはnullを返す
(関数テンプレート) |
|
(C++17)
(C++17)
(C++17)
(C++17)
(C++17)
(C++17)
(C++20)
|
variant
オブジェクトをその含まれる値として比較する
(関数テンプレート) |
|
(C++17)
|
std::swap
アルゴリズムを特殊化する
(関数テンプレート) |
ヘルパークラス
|
(C++17)
|
デフォルト構築可能でない型の
variant
の最初の代替型として使用するためのプレースホルダ型
(クラス) |
|
(C++17)
|
variant
の値への不正なアクセス時にスローされる例外
(クラス) |
|
(C++17)
|
コンパイル時に
variant
の代替型リストのサイズを取得する
(クラステンプレート) (変数テンプレート) |
|
コンパイル時にインデックスで指定された代替型の型を取得する
(クラステンプレート) (エイリアステンプレート) |
|
|
(C++17)
|
std::variant
のハッシュサポート
(クラステンプレート特殊化) |
ヘルパーオブジェクト
|
(C++17)
|
無効状態の
variant
のインデックス
(定数) |
注記
| 機能テスト マクロ | 値 | 標準 | 機能 |
|---|---|---|---|
__cpp_lib_variant
|
201606L
|
(C++17) |
std::variant
: 型安全な共用体
|
202102L
|
(C++23)
(DR17) |
std::visit
std::variant
から派生したクラス用
|
|
202106L
|
(C++23)
(DR20) |
完全な
constexpr
std::variant
|
|
202306L
|
(C++26) |
メンバー関数
visit
|
例
#include <cassert> #include <iostream> #include <string> #include <variant> int main() { std::variant<int, float> v, w; v = 42; // vはintを含む int i = std::get<int>(v); assert(42 == i); // 成功 w = std::get<int>(v); w = std::get<0>(v); // 前の行と同じ効果 w = v; // 前の行と同じ効果 // std::get<double>(v); // エラー: [int, float]にdoubleは存在しない // std::get<3>(v); // エラー: 有効なインデックス値は0と1 try { std::get<float>(w); // wはfloatではなくintを含む: 例外をスローする } catch (const std::bad_variant_access& ex) { std::cout << ex.what() << '\n'; } using namespace std::literals; std::variant<std::string> x("abc"); // 変換コンストラクタは曖昧でない場合に機能する x = "def"; // 変換代入も曖昧でない場合に機能する std::variant<std::string, void const*> y("abc"); // char const*が渡されるとvoid const*にキャストされる assert(std::holds_alternative<void const*>(y)); // 成功 y = "xyz"s; assert(std::holds_alternative<std::string>(y)); // 成功 }
出力例:
std::get: wrong index for variant
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 2901 | C++17 |
std::uses_allocator
の特殊化が提供されていたが、
variant
はアロケータを適切にサポートできない
|
特殊化を削除 |
| LWG 3990 | C++17 |
プログラムが
std::variant
の明示的特殊化または
部分特殊化を宣言可能であった |
この場合、プログラムは不適格
(診断は要求されない) |
| LWG 4141 | C++17 |
ストレージ割り当ての要件が
紛らわしかった |
含まれるオブジェクトは
variant
オブジェクト内に
ネストされなければならない |
関連項目
|
インプレース構築タグ
(タグ) |
|
|
(C++17)
|
オブジェクトを保持する場合と保持しない場合があるラッパー
(クラステンプレート) |
|
(C++17)
|
任意の
CopyConstructible
型のインスタンスを保持するオブジェクト
(クラス) |