std::optional<T>::operator=
ja.cppreference.net より
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(/* see below */);
|
(3) | (C++17 から) |
template< class U = std::remove_cv_t<T> >
optional& operator=( U&& value );
|
(4) | (C++17 から) (C++20 から constexpr) |
template< class U >
optional& operator=( const optional<U>& other );
|
(5) | (C++17 から) (C++20 から constexpr) |
template< class U >
optional& operator=( optional<U>&& other );
|
(6) | (C++17 から) (C++20 から constexpr) |
*this の内容を other の内容で置き換えます。
1) 呼び出し前に
*this が値を保持している場合、保持されている値は、あたかも value().T::~T() によって呼び出されたかのように、そのデストラクタを呼び出して破棄されます。この呼び出し後、*this は値を保持しません。2,3)
other の状態を代入します。
-
*thisとotherの両方が値を保持していない場合、この関数は何の効果も持ちません。 -
*thisが値を保持しているがotherが保持していない場合、保持されている値はそのデストラクタを呼び出して破棄されます。呼び出し後、*thisは値を保持しません。 -
otherが値を保持している場合、*thisが値を保持しているかどうかに応じて、保持されている値は 直接初期化されるか、または*other(2) もしくはstd::move(*other)(3) から代入されます。移動元の optional はそれでも 値を保持していることに注意してください。 - オーバーロード (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>のいずれかがfalseである場合、オーバーロード解決に参加しません。std::is_trivially_move_constructible_v<T>、std::is_trivially_move_assignable_v<T>、std::is_trivially_destructible_v<T>がすべてtrueである場合、これはトリビアルです。
4) 完全転送代入: 呼び出し前に
*this が値を保持しているかどうかに応じて、保持されている値は std::forward<U>(value) から直接初期化されるか、または std::forward<U>(value) から代入されます。この関数は、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 であり、かつ以下の少なくとも1つが真でない限り、オーバーロード解決に参加しません:
Tが スカラ型ではない;std::decay_t<U>がTではない。
5,6)
other の状態を代入します。
-
*thisとotherの両方が値を保持していない場合、この関数は何の効果も持ちません。 -
*thisが値を保持しているがotherが保持していない場合、保持されている値はそのデストラクタを呼び出して破棄されます。呼び出し後、*thisは値を保持しません。 -
otherが値を保持している場合、*thisが値を保持しているかどうかに応じて、保持されている値は 直接初期化されるか、または*other(5) もしくはstd::move(*other)(6) から代入されます。移動元の optional はそれでも 値を保持していることに注意してください。 - これらのオーバーロードは、以下の条件が満たされない限り、オーバーロード解決に参加しません:
Tが (おそらくconst) 型std::optional<U>の任意の式から構築可能、変換可能、または代入可能ではない、すなわち、以下の12個の型特性がすべてfalseである: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>&&>
- オーバーロード (5) の場合、
std::is_constructible_v<T, const U&>とstd::is_assignable_v<T&, const U&>は両方ともtrueです。 - オーバーロード (6) の場合、
std::is_constructible_v<T, U>とstd::is_assignable_v<T&, U>は両方ともtrueです。
パラメータ
| other | - |
別の
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 > )
注記
オプショナルオブジェクト
op
は、以下の両方の方法で空のオプショナルに変換できます:
op
=
{
}
;
および
op
=
nullopt
;
。最初の式は
{
}
を使用して空の
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; // コンストラクタ s2 = s1; // 代入 s1 = "def"; // 減衰代入 (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 |
コピー/ムーブ代入演算子は、基盤となる操作がtrivialであっても
trivialではない可能性があった |
trivial性を伝播することが要求される |
| P2231R1 | C++20 | オーバーロード ( 1,4-6 ) は constexpr ではなかった | constexpr 化された |
関連項目
|
包含されている値をその場で構築する
(公開メンバ関数) |