Namespaces
Variants

std::variant

ja.cppreference.net より
 
 
ユーティリティライブラリ
言語サポート
型サポート (基本型、RTTI)
ライブラリ機能テストマクロ (C++20)
プログラムユーティリティ
可変長引数関数
コルーチンサポート (C++20)
契約サポート (C++26)
三方比較
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

汎用ユーティリティ
関係演算子 (C++20で非推奨)
整数比較関数
(C++20)(C++20)(C++20)    
(C++20)
swap と 型操作
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
共通語彙型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
 
ヘッダ <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が保持する引数で提供されたファンクタを呼び出す
(関数テンプレート)
variantが現在指定された型を保持しているかどうかをチェックする
(関数テンプレート)
インデックスまたは型(型が一意の場合)を指定してvariantの値を読み取り、エラー時には例外をスローする
(関数テンプレート)
(C++17)
インデックスまたは型(一意の場合)を指定して、指し示されるvariantの値へのポインタを取得し、エラー時にはnullを返す
(関数テンプレート)
(C++17) (C++17) (C++17) (C++17) (C++17) (C++17) (C++20)
variantオブジェクトをその含まれる値として比較する
(関数テンプレート)
std::swap アルゴリズムを特殊化する
(関数テンプレート)

ヘルパークラス

(C++17)
デフォルト構築可能でない型の variant の最初の代替型として使用するためのプレースホルダ型
(クラス)
variant の値への不正なアクセス時にスローされる例外
(クラス)
コンパイル時に variant の代替型リストのサイズを取得する
(クラステンプレート) (変数テンプレート)
コンパイル時にインデックスで指定された代替型の型を取得する
(クラステンプレート) (エイリアステンプレート)
std::variant のハッシュサポート
(クラステンプレート特殊化)

ヘルパーオブジェクト

無効状態の 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 型のインスタンスを保持するオブジェクト
(クラス)