std::expected<T,E>::operator=
來自 cppreference.com
主模板 |
||
constexpr expected& operator=( const expected& other ); |
(1) | (C++23 起) |
constexpr expected& operator=( expected&& other ) noexcept(/* 見下方 */); |
(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
物件賦新值。
目錄 |
[編輯] 引數
其他 | - | 另一個 expected 物件,將其所含的值賦給當前物件 |
v | - | 要賦值給包含值的值 |
e | - | std::unexpected 物件,將其所含的值賦給當前物件 |
newval | - | 要構造的所含值 |
oldval | - | 要銷燬的所含值 |
args | - | 用作 newval 初始化的引數 |
[編輯] 效果
[編輯] 主模板賦值運算子
1,2) 將 other 的狀態賦給 *this。
如果
has_value()
和 rhs.has_value() 的值不同(即 *this 和 other 中一個含有期望值 val
,而另一個含有非期望值 unex
),則呼叫僅用於闡釋的函式模板 reinit-expected
來安全地更新狀態。1) 所含值的賦值方式如下
has_value() 的值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();
|
2) 所含值的賦值方式如下
has_value() 的值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();。3) 期望值的賦值方式如下
has_value() 的值has_value() 的值
|
等價於 |
---|---|
true | val = std::forward<U>(v);
|
false | reinit-expected (val , unex , std::forward<U>(v));has_val = false;
|
4,5) 非期望值的賦值方式如下
過載 | has_value() 的值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 部分特化賦值運算子
6) 非期望值的賦值或銷燬方式如下
has_value() 的值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();
|
7) 非期望值的賦值或銷燬方式如下
has_value() 的值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());
|
8,9) 非期望值的賦值方式如下
過載 | has_value() 的值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) { // Case 1: the construction of “new_val” is non-throwing: // “new_val” can be directly constructed after destroying “old_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)...); } // Case 2: the move construction of “new_val” is non-throwing: // constuct a temporary NewType object first // (“old_val” is left intact if an exception is thrown from this construction) else if constexpr (std::is_nothrow_move_constructible_v<NewType>) { NewType temp(std::forward<Args>(args)...); // may throw std::destroy_at(std::addressof(old_val)); std::construct_at(std::addressof(new_val), std::move(temp)); } // Case 3: the construction of “new_val” is potentially-throwing: // a backup of “old_val” is required in order to recover from an exception else { OldType temp(std::move(old_val)); // may throw std::destroy_at(std::addressof(old_val)); try { std::construct_at(std::addressof(new_val), std::forward<Args>(args)...); // may throw } catch (...) { std::construct_at(std::addressof(old_val), std::move(temp)); throw; } } }
當賦值操作將使 *this 持有備選值時(即從期望值變為非期望值,或從非期望值變為期望值),會呼叫此函式模板。
在這種情況下,舊值 oldval 需要在構造新值 newval 之前被銷燬。然而,newval 的構造可能會丟擲異常。為了提供強異常安全保證,在重新丟擲異常之前需要恢復舊值,以便在處理異常時 *this 仍處於有效狀態。
[編輯] 返回值
1-9) *this
[編輯] 約束和補充資訊
[編輯] 主模板賦值運算子
1) 除非以下所有條件均為 true,否則此過載被定義為刪除的
2) 僅若以下所有條件均為 true,此過載才會參與過載決議
3) 此過載僅在滿足以下所有條件時才參與過載決議
- std::is_same_v<expected, std::remove_cvref_t<U>> 為 false。
- std::remove_cvref_t<U> 不是
std::unexpected
的特化。 - 以下所有條件均為 true
4) 僅若以下所有條件均為 true,此過載才會參與過載決議
- 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>
5) 僅若以下所有條件均為 true,此過載才會參與過載決議
[編輯] void 部分特化賦值運算子
8) 僅若 std::is_constructible_v<E, const G&> 和 std::is_assignable_v<E&, const G&> 均為 true,此過載才會參與過載決議。
[編輯] 異常
2)
noexcept 規範:
noexcept(
std::is_nothrow_move_constructible_v<T> && std::is_nothrow_move_assignable_v<T> &&
7)
noexcept 規範:
noexcept(std::is_nothrow_move_constructible_v<E> && std::is_nothrow_move_assignable_v<E>)
[編輯] 示例
本節不完整 原因:無示例 |
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
LWG 3886 | C++23 | 過載 (3) 的預設模板實參曾為 T |
改為 std::remove_cv_t<T> |
LWG 4025 | C++23 | 若 E 不可移動構造或不可移動賦值,過載 (7) 曾被定義為刪除的 |
在這種情況下它現在不參與 過載決議 |
[編輯] 參閱
就地構造所含的期望值 (公開成員函式) |