std::variant<Types...>::operator=
提供: cppreference.com
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 内の値をその場で構築します (パブリックメンバ関数) |