std::variant<Types...>:: variant
|
constexpr
variant
(
)
noexcept
(
/* 下記参照 */
)
;
|
(1) | (C++17以降) |
|
constexpr
variant
(
const
variant
&
other
)
;
|
(2) | (C++17以降) |
|
constexpr
variant
(
variant
&&
other
)
noexcept
(
/* 下記参照 */
)
;
|
(3) | (C++17以降) |
|
template
<
class
T
>
constexpr variant ( T && t ) noexcept ( /* 下記参照 */ ) ; |
(4) | (C++17以降) |
|
template
<
class
T,
class
...
Args
>
|
(5) | (C++17以降) |
|
template
<
class
T,
class
U,
|
(6) | (C++17以降) |
|
template
<
std::
size_t
I,
class
...
Args
>
|
(7) | (C++17以降) |
|
template
<
std::
size_t
I,
class
U,
|
(8) | (C++17以降) |
新しい
variant
オブジェクトを構築します。
variant
を構築する(
index()
はゼロ)。
-
このコンストラクタは、代替型
T_0の値初期化が constexpr関数 の要件を満たす場合にのみ constexpr となる。 - このオーバーロードは、 std:: is_default_constructible_v < T_0 > が true の場合にのみオーバーロード解決に参加する。
variant
を構築し、含まれる値を
*
std::
get_if
<
other.
index
(
)
>
(
std::
addressof
(
other
)
)
で
直接初期化
します。それ以外の場合、
valueless_by_exception
なvariantを初期化します。
- このコンストラクタは、 std:: is_copy_constructible_v < T_i > が true でない限り、削除された定義となります。
- std:: is_trivially_copy_constructible_v < T_i > が true の場合、自明となります。
variant
を構築し、含まれる値を
std
::
move
(
*
std::
get_if
<
other.
index
(
)
>
(
std::
addressof
(
other
)
)
)
で
直接初期化
する。そうでない場合、
valueless_by_exception
なvariantを初期化する。
- このオーバーロードは、 std:: is_move_constructible_v < T_i > が true である場合にのみオーバーロード解決に参加する。
- std:: is_trivially_move_constructible_v < T_i > が true である場合、これは自明(trivial)である。
variant
を構築し、オーバーロード解決によって選択される代替型
T_j
を保持します。この選択は、
F
(
std::
forward
<
T
>
(
t
)
)
という式に対して、
F(T_i)
という仮想関数のオーバーロードが
Types...
の各
T_i
に対して存在する場合の解決結果に基づきます。ただし、縮小変換は考慮されません。
形式的には:
-
-
オーバーロード
F
(
T_i
)
は、宣言
T_i x
[
]
=
{
std::
forward
<
T
>
(
t
)
}
;
が、ある考案された変数
xに対して有効である場合にのみ考慮されます。
-
オーバーロード
F
(
T_i
)
は、宣言
T_i x
[
]
=
{
std::
forward
<
T
>
(
t
)
}
;
が、ある考案された変数
-
このオーバーロードは、以下の条件をすべて満たす場合にのみオーバーロード解決に参加します:
- sizeof... ( Types ) > 0 、
-
std::
decay_t
<
T
>
(C++20まで)
std::
remove_cvref_t
<
T
>
(C++20以降)
が
variantと同じ型でも、 std::in_place_type_t の特殊化でも、 std::in_place_index_t の特殊化でもないこと、 - std:: is_constructible_v < T_j, T > が true であること、
- かつ式 F ( std:: forward < T > ( t ) ) (Fは前述の仮想的な関数の集合)が well-formed であること。
-
このコンストラクタは、
T_jの選択されたコンストラクタが constexpr コンストラクタである場合、 constexpr コンストラクタとなります。
std::variant<std::string> v("abc"); // OK std::variant<std::string, std::string> w("abc"); // ill-formed std::variant<std::string, const char*> x("abc"); // OK, const char* を選択 std::variant<std::string, bool> y("abc"); // OK, string を選択; bool は候補ではない std::variant<float, long, double> z = 0; // OK, long を保持 // float と double は候補ではない
variant
を構築し、含まれる値を引数
std::
forward
<
Args
>
(
args
)
...
で初期化します。
-
Tの選択されたコンストラクタが constexpr コンストラクタである場合、このコンストラクタも constexpr コンストラクタとなります。 -
このオーバーロードは、
Types...
内に
Tが正確に1回のみ現れ、かつ std:: is_constructible_v < T, Args... > が true である場合にのみ、オーバーロード解決に参加します。
variant
を構築し、含まれる値を引数
il,
std::
forward
<
Args
>
(
args
)
...
で初期化します。
-
Tの選択されたコンストラクタが constexpr コンストラクタである場合、このコンストラクタも constexpr コンストラクタとなります。 -
このオーバーロードは、
Types...
内に
Tが正確に1回のみ現れ、かつ std:: is_constructible_v < T, initializer_list < U > & , Args... > が true である場合にのみ、オーバーロード解決に参加します。
I
で指定された
T_i
の代替型を持つ
variant
を構築し、引数
std::
forward
<
Args
>
(
args
)
...
で保持する値を初期化します。
-
T_iの選択されたコンストラクタが constexpr コンストラクタである場合、このコンストラクタも constexpr コンストラクタとなります。 - このオーバーロードは、 I < sizeof... ( Types ) かつ std:: is_constructible_v < T_i, Args... > が true である場合にのみ、オーバーロード解決に参加します。
I
で指定された
T_i
の代替型を持つ
variant
を構築し、引数
il,
std::
forward
<
Args
>
(
args
)
...
で保持する値を初期化します。
-
T_iの選択されたコンストラクタが constexpr コンストラクタである場合、このコンストラクタも constexpr コンストラクタとなります。 - このオーバーロードは、 I < sizeof... ( Types ) かつ std:: is_constructible_v < T_i, std:: initializer_list < U > & , Args... > が true である場合にのみ、オーバーロード解決に参加します。
目次 |
パラメータ
| other | - |
コピー/ムーブする対象の別の
variant
オブジェクト
|
| t | - | 格納される値を初期化するための値 |
| args... | - | 格納される値を初期化するための引数 |
| il | - | 格納される値を初期化するための初期化子リスト |
例外
T_i
を直接初期化する際に送出される例外をすべて送出する可能性がある。
T_i
のムーブ構築によってスローされる例外をスローする可能性がある
Types...
内の型。
T_j
の初期化によってスローされる可能性のある例外をスローする可能性があります。
注記
MSVC STLは当初 P0608R3 をC++20の変更として扱っていました。VS 2022 17.12以降、MSVC STLはP0608R3をC++17に対する欠陥報告としても扱います。
例
#include <cassert> #include <iostream> #include <string> #include <variant> #include <vector> using vector_t = std::vector<int>; auto& operator<<(auto& out, const vector_t& v) { out << "{ "; for (int e : v) out << e << ' '; return out << '}'; } int main() { // 最初の代替案を値初期化する std::variant<int, std::string> var0; assert(std::holds_alternative<int>(var0) and var0.index() == 0 and std::get<int>(var0) == 0); // std::string{"STR"}で最初の代替案を初期化する; std::variant<std::string, int> var1{"STR"}; assert(var1.index() == 0); std::cout << "1) " << std::get<std::string>(var1) << '\n'; // int == 42 で2番目の代替案を初期化する; std::variant<std::string, int> var2{42}; assert(std::holds_alternative<int>(var2)); std::cout << "2) " << std::get<int>(var2) << '\n'; // 最初の代替案を std::string{4, 'A'} で初期化する; std::variant<std::string, vector_t, float> var3 { std::in_place_type<std::string>, 4, 'A' }; assert(var3.index() == 0); std::cout << "3) " << std::get<std::string>(var3) << '\n'; // 2番目の代替案を std::vector{1,2,3,4,5} で初期化する std::variant<std::string, vector_t, char> var4 { std::in_place_type<vector_t>, {1, 2, 3, 4, 5} }; assert(var4.index() == 1); std::cout << "4) " << std::get<vector_t>(var4) << '\n'; // std::string{"ABCDE", 3} で最初の代替案を初期化する std::variant<std::string, vector_t, bool> var5 {std::in_place_index<0>, "ABCDE", 3}; assert(var5.index() == 0); std::cout << "5) " << std::get<std::string>(var5) << '\n'; // 2番目の代替案を std::vector(4, 42); で初期化する std::variant<std::string, vector_t, char> var6 {std::in_place_index<1>, 4, 42}; assert(std::holds_alternative<vector_t>(var6)); std::cout << "6) " << std::get<vector_t>(var6) << '\n'; }
出力:
1) STR
2) 42
3) AAAA
4) { 1 2 3 4 5 }
5) ABC
6) { 42 42 42 42 }
欠陥報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 2901 | C++17 |
アロケータ対応コンストラクタが提供されているが
variant
はアロケータを適切にサポートできない
|
コンストラクタを削除 |
| P0739R0 | C++17 |
変換コンストラクタテンプレートが
クラステンプレート引数推論と不適切に相互作用する |
制約を追加 |
| LWG 3024 | C++17 |
メンバー型がコピー可能でない場合、
コピーコンストラクタがオーバーロード解決に参加しない |
代わりにdelete定義 |
| P0602R4 | C++17 |
基底のコンストラクタがtrivialであっても
コピー/ムーブコンストラクタがtrivialでない可能性がある |
trivial性の伝播を要求 |
| P0608R3 | C++17 |
変換コンストラクタが盲目的にオーバーロードセットを
組み立て、意図しない変換が発生する |
縮小変換とbool変換を考慮しない |
| P1957R2 | C++17 |
bool
の変換コンストラクタが
暗黙変換を許可していなかった |
ポインタから
bool
への変換は縮小変換であり、
変換コンストラクタには bool に対する例外規定がない |