std::expected<T,E>::operator=
来自 cppreference.cn
主模板 |
||
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
对象赋值新值。
目录 |
[编辑] 参数
other | - | 另一个 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) 包含的值按如下方式赋值
Value ofhas_value() |
Value of other.has_value() | |
---|---|---|
true | false | |
true | val = *other;
|
reinit-expected (unex , val , other.error());
|
false | reinit-expected (val , unex , *other);
|
unex = other.error();
|
2) 包含的值按如下方式赋值
Value ofhas_value() |
Value of 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) 期望值按如下方式赋值
Value ofhas_value() |
等价于 |
---|---|
true | val = std::forward<U>(v);
|
false | reinit-expected (val , unex , std::forward<U>(v));has_val = false;
|
4,5) 非期望值按如下方式赋值
重载 | Value ofhas_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) 非期望值被赋值或销毁,如下所示
Value ofhas_value() |
Value of 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) 非期望值被赋值或销毁,如下所示
Value ofhas_value() |
Value of 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) 非期望值按如下方式赋值
重载 | Value ofhas_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++ 标准。
DR | 应用于 | 已发布行为 | 正确行为 |
---|---|---|---|
LWG 3886 | C++23 | 重载 (3) 的默认模板参数为 T |
更改为 std::remove_cv_t<T> |
LWG 4025 | C++23 | 如果 E 不是,则重载 (7) 被定义为已删除可移动构造或不可移动赋值 |
在这种情况下,它不参与 重载决议 |
[编辑] 参见
就地构造期望值 (公共成员函数) |