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 修飾が異なるバージョンを保持することができます。
集成体初期化 における union の動作と一貫して、デフォルト構築された variant は、その最初の代替型の値を保持します。ただし、その最初の代替型がデフォルト構築可能でない場合 (その場合、variant もデフォルト構築可能ではありません) は除きます。ヘルパークラス std::monostate は、そのような variant をデフォルト構築可能にするために使用できます。
テンプレート引数なしで std::variant の定義をインスタンス化するプログラムは、ill-formed です。代わりに std::variant<std::monostate> を使用できます。
プログラムが 明示的 または 部分的 特殊化を 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
型のインスタンスを保持するオブジェクト
(クラス) |