std::variant<Types...>::operator=
提供: cppreference.com
<tbody>
</tbody>
constexpr variant& operator=( const variant& rhs ); |
(1) | (C++17以上) |
constexpr variant& operator=( variant&& rhs ) noexcept(/* see below */); |
(2) | (C++17以上) |
template< class T > variant& operator=( T&& t ) noexcept(/* see below */); |
(3) | (C++17以上) |
新しい値を既存の variant オブジェクトに代入します。
1) コピー代入。
*thisとrhsがどちらも valueless by exception であれば、何もしません。- そうでなく、
rhsが valueless だけれども*thisがそうでなければ、*thisに格納されている値は破棄され、 valueless になります。 - そうでなく、
rhsが*thisと同じ選択肢を保持していれば、rhsに格納されている値が*thisに格納されている値に代入されます。 例外が投げられた場合、*thisは valueless になりません。 値はその選択肢のコピー代入の例外安全性保証によります。 - そうでなく、
rhsの保持している選択肢が無例外コピー構築可能であるか無例外ムーブ構築可能で「ない」かのいずれかであれば (それぞれ std::is_nothrow_copy_constructible および std::is_nothrow_move_constructible によって判定されます)、this->emplace<rhs.index()>(get<rhs.index()>(rhs))と同等です。 - そうでなければ、
this->operator=(variant(rhs))と同等です。 (2) で説明しているように、*thisは valueless_by_exception になるかもしれないことに注意してください。
このオーバーロードは、
Types... 内のすべての T_i について std::is_copy_constructible_v<T_i> と std::is_copy_assignable_v<T_i> がどちらも true でなければ、削除されたものとして定義されます。 このオーバーロードは、 Types... 内のすべての T_i について std::is_trivially_copy_constructible_v<T_i>、 std::is_trivially_copy_assignable_v<T_i> および std::is_trivially_destructible_v<T_i> がすべて true であれば、トリビアルです。2) ムーブ代入。
*thisとrhsがどちらも valueless by exception であれば、何もしません。- そうでなく、
rhsが valueless だけれども*thisがそうでなければ、*thisに格納されている値は破棄され、 valueless になります。 - そうでなく、
rhsが*thisと同じ選択肢を保持していれば、std::get<j>(std::move(rhs))が*thisに格納されている値に代入されます。 ただしjはindex()です。 例外が投げられた場合、*thisは valueless になりません。 値はその選択肢のムーブ代入の例外安全性保証によります。 - そうでなければ (
rhsと*thisが異なる選択肢を保持している場合)、this->emplace<rhs.index()>(get<rhs.index()>(std::move(rhs)))と同等です。T_iのムーブコンストラクタによって例外が投げられた場合、*thisは valueless_by_exception になります。
このオーバーロードは、
Types... 内のすべての T_i について std::is_move_constructible_v<T_i> と std::is_move_assignable_v<T_i> がどちらも true である場合にのみ、オーバーロード解決に参加します。 このオーバーロードは、 Types... 内のすべての T_i について std::is_trivially_move_constructible_v<T_i>、 std::is_trivially_move_assignable_v<T_i> および std::is_trivially_destructible_v<T_i> がすべて true であれば、トリビアルです。3) 変換代入。
- そのときのスコープにおいて
Types...のすべてのT_iに対して架空の関数F(T_i)のオーバーロードが存在した場合に式F(std::forward<T>(t))に対するオーバーロード解決によって選択されるであろう選択肢の型T_jを決定します。 *thisがすでにT_jを保持していれば、std::forward<T>(t)が*thisに格納されている値に代入されます。 例外が投げられた場合、*thisは valueless になりません。 値は呼ばれた代入の例外安全性保証によります。- そうでなく、
std::is_nothrow_constructible_v<T_j, T> || !std::is_nothrow_move_constructible_v<T_j>がtrueであれば、this->emplace<j>(std::forward<T>(t))と同等です。 - そうでなければ、
this->operator=(variant(std::forward<T>(t)))と同等です。
このオーバーロードは、std::decay_t<T> (C++20未満)std::remove_cvref_t<T> (C++20以上) が variant と同じ型でなく、 std::is_assignable_v<T_j&, T> が true であり、 std::is_constructible_v<T_j, T> が true であり、式 F(std::forward<T>(t)) (ただし F は前述の架空の関数のオーバーロード集合です) が well-formed である場合にのみ、オーバーロード解決に参加します。
std::variant<string> v1;
v1 = "abc"; // OK
std::variant<std::string, std::string> v2;
v2 = "abc"; // エラー
std::variant <std::string, bool> v3;
v3 = "abc"; // OK、 string が選択されます。 bool は候補ではありません。
std::variant<float, long, double> v4; // float 保持します。
v4 = 0; // OK、 long を保持します。 float および double は候補ではありません。
引数
| rhs | - | 別の variant
|
| t | - | variant の選択肢のいずれかに変換可能な値 |
戻り値
*this。
例外
1) あらゆる選択肢の代入、コピーおよびムーブ初期化によって投げられるあらゆる例外が投げられる可能性があります。
2)
noexcept 指定:
noexcept(((std::is_nothrow_move_constructible_v<Types> && std::is_nothrow_move_assignable_v<Types>) && ...))3)
noexcept 指定:
noexcept(std::is_nothrow_assignable_v<T_j&, T> && std::is_nothrow_constructible_v<T_j, T>)例
| This section is incomplete Reason: no example |
欠陥報告
以下の動作変更欠陥報告は以前に発行された C++ 標準に遡って適用されました。
| DR | 適用先 | 発行時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 3024 | C++17 | copy assignment operator doesn't participate in overload resolution if any member type is not copyable | defined as deleted instead |
| P0602R4 | C++17 | copy/move assignment may not be trivial even if underlying operations are trivial | required to propagate triviality |
| P0608R3 | C++17 | converting assignment blindly assembles an overload set, leading to unintended conversions | narrowing and boolean conversions not considered |
関連項目
| variant 内の値をその場で構築します (パブリックメンバ関数) |