std::optional<T>::operator=
From cppreference.com
optional& operator=( std::nullopt_t ) noexcept; |
(1) | (C++17以降) (C++20 以降 constexpr) |
constexpr optional& operator=( const optional& other ); |
(2) | (C++17以降) |
constexpr optional& operator= ( optional&& other ) noexcept(/* 以下参照 */); |
(3) | (C++17以降) |
template< class U > optional& operator=( const optional<U>& other ); |
(4) | (C++17以降) (C++20 以降 constexpr) |
template< class U > optional& operator=( optional<U>&& other ); |
(5) | (C++17以降) (C++20 以降 constexpr) |
template< class U = std::remove_cv_t<T> > optional& operator=( U&& value ); |
(6) | (C++17以降) (C++20 以降 constexpr) |
内容は *this を other の内容で置き換えます。
1) *this が値を保持している場合、保持している値を破棄するために
val ->T::~T() を呼び出します。そうでなければ、効果はありません。*this はこの呼び出し後、値を保持しなくなります。2-5) other の状態を代入します。other.has_value() はこの呼び出し後、*this.has_value() と同等になります。
| 効果 | *this は値を保持している | *this は値を保持していない |
|---|---|---|
| other は値を保持している |
|
|
| other は値を保持していない | val ->T::~T() を呼び出して、保持されている値を破棄します。 |
効果なし |
2) std::is_copy_constructible_v<T> または std::is_copy_assignable_v<T> が false の場合、代入演算子は削除されていると定義されます。
std::is_trivially_copy_constructible_v<T>、std::is_trivially_copy_assignable_v<T>、および std::is_trivially_destructible_v<T> がすべて true の場合、代入演算子は自明です。
3) このオーバーロードは、std::is_move_constructible_v<T> と std::is_move_assignable_v<T> の両方が true の場合にのみ、オーバーロード解決に参加します。
std::is_trivially_move_constructible_v<T>、std::is_trivially_move_assignable_v<T>、および std::is_trivially_destructible_v<T> がすべて true の場合、代入演算子は自明です。
4,5) これらのオーバーロードは、以下のすべての条件が満たされた場合にのみ、オーバーロード解決に参加します。
- 以下の12個の値がすべて false であること[1]。
- std::is_constructible_v<T, std::optional<U>&>
- std::is_constructible_v<T, const std::optional<U>&>
- std::is_constructible_v<T, std::optional<U>&&>
- std::is_constructible_v<T, const std::optional<U>&&>
- std::is_convertible_v<std::optional<U>&, T>
- std::is_convertible_v<const std::optional<U>&, T>
- std::is_convertible_v<std::optional<U>&&, T>
- std::is_convertible_v<const std::optional<U>&&, T>
- std::is_assignable_v<T&, std::optional<U>&>
- std::is_assignable_v<T&, const std::optional<U>&>
- std::is_assignable_v<T&, std::optional<U>&&>
- std::is_assignable_v<T&, const std::optional<U>&&>
- オーバーロード (4) の場合、std::is_constructible_v<T, const U&> および std::is_assignable_v<T&, const U&> が両方とも true であること。
- オーバーロード (5) の場合、std::is_constructible_v<T, U> および std::is_assignable_v<T&, U> が両方とも true であること。
6) *this が値を保持している場合、保持している値に std::forward<U>(value) を代入します。そうでなければ、std::forward<U>(value) を使用して、保持している値を直接(非リスト)初期化します。*this はこの呼び出し後、値を保持するようになります。
このオーバーロードは、以下のすべての条件が満たされた場合にのみオーバーロード解決に参加します。
- std::decay_t<U>(C++20まで)std::remove_cvref_t<U>(C++20以降) は std::optional<T> ではない。
- std::is_constructible_v<T, U>がtrueであること。
- std::is_assignable_v<T&, U> が true。
- 以下のいずれかの条件が満たされる。
-
Tは スカラー型ではない。 - std::decay_t<U> は
Tではない。
-
- ↑ 言い換えると、
Tは(const修飾されている可能性のある)std::optional<U> 型のいかなる式からも構築、変換、または代入可能ではない。
目次 |
[編集] パラメータ
| その他 | - | 代入する値を持つ別のoptionalオブジェクト。 |
| value | - | 保持されている値に代入する値。 |
[編集] 戻り値
*this
[編集] 例外
2-6)
T のコンストラクタまたは代入演算子によってスローされた例外をスローします。例外がスローされた場合、*this の初期化状態(および (2-5) の場合は other の初期化状態)は変更されません。つまり、オブジェクトが値を保持していた場合はそのまま保持し、そうでない場合はそのまま保持しません。value の内容、および *this と other の保持されている値は、例外が発生した操作(コピーコンストラクタ、ムーブ代入など)の例外安全保証に依存します。3) 以下のようになります。
noexcept 指定:
noexcept(std::is_nothrow_move_assignable_v<T> &&
std::is_nothrow_move_constructible_v<T>)
std::is_nothrow_move_constructible_v<T>)
[編集] 注記
optionalオブジェクト op は、op = {}; および op = nullopt; の両方で空の optional にすることができます。最初の式は、空の optional オブジェクトを {} で構築し、それを op に代入します。
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_optional |
202106L |
(C++20) (DR20) |
完全な constexpr ((1)、(4-6)) |
[編集] 例
このコードを実行
#include <iostream> #include <optional> int main() { std::optional<const char*> s1 = "abc", s2; // constructor s2 = s1; // assignment s1 = "def"; // decaying assignment (U = char[4], T = const char*) std::cout << *s2 << ' ' << *s1 << '\n'; }
出力
abc def
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 3886 | C++17 | オーバーロード (6) のデフォルトテンプレート引数が T でした。 |
std::remove_cv_t<T>に変更されました。 |
| P0602R4 | C++17 | コピー/ムーブ代入演算子は自明ではない場合があります。 基になる操作が自明であっても。 |
自明性の伝播が必要です。 |
| P2231R1 | C++20 | オーバーロード (1,4-6) は constexpr ではありませんでした。 | constexprではありませんでした。 |
[編集] 関連項目
| 保持する値を直接構築する (public member function) |