名前空間
変種
操作

std::variant

From cppreference.com
< cpp‎ | utility
 
 
ユーティリティライブラリ
言語サポート
型のサポート (基本型、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)
スワップ型操作
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
共通語彙型
(C++11)
(C++17)
(C++17)
variant
(C++17)
(C++11)
(C++17)
(C++23)



 
 
ヘッダ <variant> で定義
template< class... Types >
class variant;
(C++17以降)

クラステンプレート std::variant は、型安全な共用体 (union) を表します。

variant のインスタンスは、任意の時点で、その代替型のいずれかの値を保持するか、エラーの場合は値を保持しません(この状態を達成するのは困難です。valueless_by_exceptionを参照してください)。

共用体と同様に、variant があるオブジェクト型 T の値を保持する場合、その T オブジェクトは variant オブジェクト内にネストされます。

variant は、参照、配列、または型 void を保持することはできません。

variant は、同じ型を複数回保持することや、同じ型のcv修飾が異なるバージョンを保持することが許可されています。

集成体初期化中の共用体の振る舞いと一致して、デフォルト構築された variant は、その最初の代替型の値を保持します。ただし、その代替型がデフォルト構築可能でない場合を除きます(その場合、variant もデフォルト構築可能ではありません)。ヘルパークラス std::monostate を使用して、そのような variant をデフォルト構築可能にすることができます。

テンプレート引数なしで std::variant の定義をインスタンス化するプログラムは、不適格 (ill-formed) です。代わりに std::variant<std::monostate> を使用できます。

プログラムが std::variant明示的または部分的な特殊化を宣言した場合、そのプログラムは不適格 (ill-formed) であり、診断は要求されません。

目次

[編集] テンプレートパラメータ

- この 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 が保持する引数で、与えられたファンクタを呼び出す
(function template) [編集]
variant が現在指定された型を保持しているかを確認する
(function template) [編集]
インデックスまたは型(型が一意である場合)を指定して variant の値を読み取る。エラーの場合は例外をスローする
(function template) [編集]
(C++17)
インデックスまたは型(一意である場合)を指定して、ポインタが指す variant の値へのポインタを取得する。エラーの場合は null を返す
(function template) [編集]
(C++17)(C++17)(C++17)(C++17)(C++17)(C++17)(C++20)
variant オブジェクトを、その含まれる値として比較する
(function template) [編集]
std::swap アルゴリズムを特殊化する
(function template) [編集]

[編集] ヘルパークラス

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

[編集] ヘルパーオブジェクト

無効な状態にある variant のインデックス
(constant) [編集]

[編集] ノート

機能テストマクロ 規格 機能
__cpp_lib_variant 201606L (C++17) std::variant: 型安全な共用体
202102L (C++23)
(DR17)
std::variant から派生したクラスに対する std::visit
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 contains int
    int i = std::get<int>(v);
    assert(42 == i); // succeeds
    w = std::get<int>(v);
    w = std::get<0>(v); // same effect as the previous line
    w = v; // same effect as the previous line
 
//  std::get<double>(v); // error: no double in [int, float]
//  std::get<3>(v);      // error: valid index values are 0 and 1
 
    try
    {
        std::get<float>(w); // w contains int, not float: will throw
    }
    catch (const std::bad_variant_access& ex)
    {
        std::cout << ex.what() << '\n';
    }
 
    using namespace std::literals;
 
    std::variant<std::string> x("abc");
    // converting constructors work when unambiguous
    x = "def"; // converting assignment also works when unambiguous
 
    std::variant<std::string, void const*> y("abc");
    // casts to void const* when passed a char const*
    assert(std::holds_alternative<void const*>(y)); // succeeds
    y = "xyz"s;
    assert(std::holds_alternative<std::string>(y)); // succeeds
}

実行結果の例

std::get: wrong index for variant

[編集] 欠陥報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
LWG 2901 C++17 std::uses_allocator の特殊化が提供されていたが、
variant はアロケータを適切にサポートできない
特殊化は削除された
LWG 3990 C++17 プログラムが std::variant の明示的または
部分的な特殊化を宣言できていた
この場合、プログラムは不適格 (ill-formed) になる
(診断は要求されない)
LWG 4141 C++17 variant オブジェクト内に
紛らわしかった
保持されるオブジェクトは
ネストして格納するための要件

[編集] 関連項目

インプレース構築タグ
(タグ)[編集]
(C++17)
オブジェクトを保持しているかもしれないし、していないかもしれないラッパー
(クラステンプレート) [編集]
(C++17)
任意の CopyConstructible な型のインスタンスを保持するオブジェクト
(クラス) [編集]
English 日本語 中文(简体) 中文(繁體)