名前空間
変種
操作

std::variant

提供: cppreference.com
< cpp‎ | utility
 
 
 
 
ヘッダ <variant> で定義
template <class... Types>
class variant;
(C++17およびそれ以降)

クラステンプレート std::variant は型安全な union を表します。 std::variant のインスタンスは任意の時点でその型の選択肢のいずれかの値を保持します。 また、エラーが発生した場合は値を保持しないこともあります (この状態を得るのは簡単ではありません。 valueless_by_exception を参照してください)。

union と同様に、 variant が何らかのオブジェクト型 T の値を保持している場合、 T のオブジェクト表現は variant 自身のオブジェクト表現内に直接確保されます。 variant が追加の (動的) メモリを確保することはありません。

variant は参照、配列、および void 型を保持することはできません。 空の variant もまた ill-formed です (代わりに std::variant<std::monostate> を使ってください)。

variant の選択肢に同じ型を2つ以上指定したり、同じ型の cv 修飾が異なるバージョンを指定したりできます。

集成体初期化に関する union の動作との一貫性のため、デフォルト構築された variant はその最初の選択肢の値を保持します。 ただしその選択肢がデフォルト構築可能でない場合は除きます (その場合、 variant もデフォルト構築可能でなくなります)。 ヘルパークラス std::monostate はそのような variant をデフォルト構築可能にするために使うことができます。

目次

[編集] テンプレート引数

Types - この variant に格納するかもしれない型。 すべての型は非配列なオブジェクト型 (またはその cv 修飾された型) でなければなりません。

[編集] メンバ関数

variant オブジェクトを構築します
(パブリックメンバ関数) [edit]
格納されている値と共に variant を破棄します
(パブリックメンバ関数) [edit]
variant を代入します
(パブリックメンバ関数) [edit]
観察
variant が保持している選択肢の0から始まるインデックスを返します
(パブリックメンバ関数) [edit]
variant が無効な状態かどうか調べます
(パブリックメンバ関数) [edit]
変更
variant 内の値をその場で構築します
(パブリックメンバ関数) [edit]
別の variant と交換します
(パブリックメンバ関数) [edit]

[編集] 非メンバ関数

(C++17)
1個以上の variant が保持している引数を渡して指定された関数オブジェクトを呼びます
(関数テンプレート) [edit]
variant が現在指定された型を保持しているかどうか調べます
(関数テンプレート) [edit]
指定されたインデックスまたは型 (一意な場合) の値を variant から読み込みます。 エラーの場合は例外を投げます
(関数テンプレート) [edit]
(C++17)
指定されたインデックスまたは型 (一意な場合) の値へのポインタを取得します。 エラーの場合はヌルを返します
(関数テンプレート) [edit]
格納されている値として variant オブジェクトを比較します
(関数テンプレート) [edit]
std::swap アルゴリズムの特殊化
(関数) [edit]

[編集] ヘルパークラス

(C++17)
デフォルト構築可能でない型の variant で最初の選択肢として使用するためのプレースホルダー型
(クラス) [edit]
variant の値への無効なアクセスで投げられる例外
(クラス) [edit]
variant の選択肢のリストのサイズをコンパイル時に取得します
(クラステンプレート) (変数テンプレート) [edit]
インデックスで指定された選択肢の型をコンパイル時に取得します
(クラステンプレート) (エイリアステンプレート) [edit]
std::hash アルゴリズムの特殊化
(クラステンプレートの特殊化) [edit]

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

無効な状態にある variant のインデックス
(定数) [edit]

[編集] 欠陥報告

以下の動作変更欠陥報告は以前に発行された C++ 標準に遡って適用されました。

DR 適用先 発行時の動作 正しい動作
LWG 2901 C++17 std::uses_allocator の特殊化が提供されていますが、 variant はアロケータを適切にサポートできません 仕様は削除されました

[編集]

#include <variant>
#include <string>
#include <cassert>
 
using namespace std::literals;
 
int main()
{
    std::variant<int, float> v, w;
    v = 12; // v contains int
    int i = std::get<int>(v);
    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&) {}
 
    std::variant<std::string> x("abc"); // converting constructors work when unambiguous
    x = "def"; // converting assignment also works when unambiguous
 
    std::variant<std::string, bool> y("abc"); // casts to bool when passed a char const *
    assert(std::holds_alternative<bool>(y)); // succeeds
    y = "xyz"s;
    assert(std::holds_alternative<std::string>(y)); //succeeds
}


[編集] 関連項目

その場構築のタグ
(クラステンプレート) [edit]
(C++17)
値を保持するかもしれないし保持しないかもしれないラッパー
(クラステンプレート) [edit]
(C++17)
CopyConstructible な型の任意のインスタンスを保持するオブジェクト
(クラス) [edit]