std::expected<T,E>:: operator=
|
プライマリテンプレート
|
||
|
constexpr
expected
&
operator
=
(
const
expected
&
other
)
;
|
(1) | (C++23以降) |
|
constexpr
expected
&
operator
=
(
expected
&&
other
)
noexcept ( /* see below */ ) ; |
(2) | (C++23以降) |
|
template
<
class
U
=
std::
remove_cv_t
<
T
>
>
constexpr expected & operator = ( U && v ) ; |
(3) | (C++23以降) |
|
template
<
class
G
>
constexpr expected & operator = ( const std:: unexpected < G > & e ) ; |
(4) | (C++23以降) |
|
template
<
class
G
>
constexpr expected & operator = ( std:: unexpected < G > && e ) ; |
(5) | (C++23以降) |
|
void
部分特殊化
|
||
|
constexpr
expected
&
operator
=
(
const
expected
&
other
)
;
|
(6) | (C++23以降) |
|
constexpr
expected
&
operator
=
(
expected
&&
other
)
noexcept ( /* 下記参照 */ ) ; |
(7) | (C++23以降) |
|
template
<
class
G
>
constexpr expected & operator = ( const std:: unexpected < G > & e ) ; |
(8) | (C++23以降) |
|
template
<
class
G
>
constexpr expected & operator = ( std:: unexpected < G > && e ) ; |
(9) | (C++23以降) |
|
ヘルパー関数テンプレート
|
||
|
template
<
class
T,
class
U,
class
...
Args
>
constexpr void /*reinit-expected*/ ( T & newval, U & oldval, Args && ... args ) |
(10) |
(C++23以降)
( 説明専用* ) |
既存の
expected
オブジェクトに新しい値を割り当てます。
目次 |
パラメータ
| other | - |
代入する値を含む別の
expected
オブジェクト
|
| v | - | 含まれる値に代入する値 |
| e | - | std::unexpected オブジェクト(代入する値を含む) |
| newval | - | 構築される含まれる値 |
| oldval | - | 破棄される含まれる値 |
| args | - | newval の初期化子として使用される引数 |
効果
プライマリテンプレート代入演算子
has_value()
と
rhs.
has_value
(
)
が異なる値を持つ場合(つまり、
*
this
と
other
の一方が期待値を含み、他方が非期待値を含む場合)、説明専用の関数テンプレート
reinit-expected
が呼び出され、状態を安全に更新します。
has_value()
の値
|
other. has_value ( ) の値 | |
|---|---|---|
| true | false | |
| true |
val
=
*
other
;
|
reinit-expected
(
unex
,
val
, other.
error
(
)
)
;
|
| false |
reinit-expected
(
val
,
unex
,
*
other
)
;
|
unex
=
other.
error
(
)
;
|
has_value()
の値
|
other. has_value ( ) の値 | |
|---|---|---|
| true | false | |
| true |
val
=
std
::
move
(
*
other
)
;
|
reinit-expected
(
unex
,
val
, std
::
move
(
other.
error
(
)
)
)
;
|
| false |
reinit-expected
(
val
,
unex
,
std
::
move
(
*
other
)
)
;
|
unex
=
std
::
move
(
other.
error
(
)
)
;
|
has_val
=
other.
has_value
(
)
;
を実行します。
has_value()
の値
|
同等の処理 |
|---|---|
| true |
val
=
std::
forward
<
U
>
(
v
)
;
|
| false |
reinit-expected
(
val
,
unex
,
std::
forward
<
U
>
(
v
)
)
;
has_val
=
false
;
|
| オーバーロード |
has_value()
の値
|
同等の処理 |
|---|---|---|
| ( 4 ) | true |
reinit-expected
(
val
,
unex
,
std::
forward
<
const
G
&
>
(
e.
error
(
)
)
)
;
has_val
=
false
;
|
| false |
unex
=
std::
forward
<
const
G
&
>
(
e.
error
(
)
)
;
|
|
| ( 5 ) | true |
reinit-expected
(
val
,
unex
,
std::
forward
<
G
>
(
e.
error
(
)
)
)
;
has_val
=
false
;
|
| false |
unex
=
std::
forward
<
G
>
(
e.
error
(
)
)
;
|
void 部分特殊化代入演算子
has_value()
の値
|
other. has_value ( ) の値 | |
|---|---|---|
| true | false | |
| true | (効果なし) |
std::
construct_at
(
std::
addressof
(
unex
)
, rhs.
unex
)
;
has_val
=
false
;
|
| false |
std::
destroy_at
(
std::
addressof
(
unex
)
)
;
has_val
=
true
;
|
unex
=
other.
error
(
)
;
|
has_value()
の値
|
other. has_value ( ) の値 | |
|---|---|---|
| true | false | |
| true | (効果なし) |
std::
construct_at
(
std::
addressof
(
unex
)
,
std
::
move
(
rhs.
unex
)
)
;
has_val
=
false
;
|
| false |
std::
destroy_at
(
std::
addressof
(
unex
)
)
;
has_val
=
true
;
|
unex
=
std
::
move
(
other.
error
(
)
)
;
|
| オーバーロード |
has_value()
の値
|
同等の処理 |
|---|---|---|
| ( 8 ) | true |
std::
construct_at
(
std::
addressof
(
unex
)
,
std::
forward
<
const
G
&
>
(
e.
error
(
)
)
)
;
has_val
=
false
;
|
| false |
unex
=
std::
forward
<
const
G
&
>
(
e.
error
(
)
)
;
|
|
| ( 9 ) | true |
std::
construct_at
(
std::
addressof
(
unex
)
,
std::
forward
<
G
>
(
e.
error
(
)
)
)
;
has_val
=
false
;
|
| false |
unex
=
std::
forward
<
G
>
(
e.
error
(
)
)
;
|
ヘルパー関数テンプレート
説明専用の関数テンプレート
reinit-expected
は以下のように「定義」される:
template<class NewType, class OldType, class... Args> constexpr void reinit-expected(NewType& new_val, OldType& old_val, Args&&... args) { // ケース1: 「new_val」の構築が例外を投げない場合: // 「old_val」を破棄した後、「new_val」を直接構築可能 if constexpr (std::is_nothrow_constructible_v<NewType, Args...>) { std::destroy_at(std::addressof(old_val)); std::construct_at(std::addressof(new_val), std::forward<Args>(args)...); } // ケース2: 「new_val」のムーブ構築が例外を投げない場合: // 一時的なNewTypeオブジェクトを先に構築 // (この構築から例外が投げられた場合、「old_val」はそのまま保持される) else if constexpr (std::is_nothrow_move_constructible_v<NewType>) { NewType temp(std::forward<Args>(args)...); // 例外を投げる可能性あり std::destroy_at(std::addressof(old_val)); std::construct_at(std::addressof(new_val), std::move(temp)); } // ケース3: 「new_val」の構築が例外を投げる可能性がある場合: // 例外からの回復のために「old_val」のバックアップが必要 else { OldType temp(std::move(old_val)); // 例外を投げる可能性あり std::destroy_at(std::addressof(old_val)); try { std::construct_at(std::addressof(new_val), std::forward<Args>(args)...); // 例外を投げる可能性あり } catch (...) { std::construct_at(std::addressof(old_val), std::move(temp)); throw; } } }
この関数テンプレートは、代入によって * this が代替値を保持するようになる場合(すなわち、expected値からunexpected値へ、またはunexpected値からexpected値へ変更される場合)に呼び出されます。
この場合、古い値 oldval は新しい値 newval の構築前に破棄される必要があります。しかし、 newval の構築は例外をスローする可能性があります。 strong exception safety guarantee を提供するためには、例外を再スローする前に古い値を復元する必要があり、これにより例外処理中も * this が有効な状態を維持します。
戻り値
制約条件と補足情報
プライマリテンプレート代入演算子
- std:: is_same_v < expected, std:: remove_cvref_t < U >> が false であること
-
std::
remove_cvref_t
<
U
>
が
std::unexpectedの特殊化ではないこと -
以下の全ての値が
true
であること:
- std:: is_constructible_v < T, U >
- std:: is_assignable_v < T & , U >
-
std::
is_nothrow_constructible_v
<
T, U
>
||
std::
is_nothrow_move_constructible_v
<
T
>
||
std:: is_nothrow_move_constructible_v < E >
- std:: is_constructible_v < E, const G & >
- std:: is_assignable_v < E & , const G & >
-
std::
is_nothrow_constructible_v
<
E,
const
G
&
>
||
std::
is_nothrow_move_constructible_v
<
T
>
||
std:: is_nothrow_move_constructible_v < E >
- std:: is_constructible_v < E, G >
- std:: is_assignable_v < E & , G >
-
std::
is_nothrow_constructible_v
<
E, G
>
||
std::
is_nothrow_move_constructible_v
<
T
>
||
std:: is_nothrow_move_constructible_v < E >
void 部分特殊化代入演算子
例外
std::
is_nothrow_move_constructible_v
<
T
>
&&
std::
is_nothrow_move_assignable_v
<
T
>
&&
例
|
このセクションは不完全です
理由: 例がありません |
欠陥報告
以下の動作変更に関する欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 3886 | C++23 |
オーバーロード
(
3
)
のデフォルトテンプレート引数は
T
であった
|
std:: remove_cv_t < T > に変更 |
| LWG 4025 | C++23 |
オーバーロード
(
7
)
は
E
がムーブ構築可能でないか
ムーブ代入可能でない場合に削除定義されていた |
この場合、オーバーロード解決に
参加しない |
関連項目
|
期待される値をその場で構築する
(公開メンバ関数) |