Namespaces
Variants

std::expected<T,E>:: operator=

From cppreference.net
Utilities library
主模板
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 ( /* see below */ ) ;
(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) 所含值的赋值规则如下:
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() 的值 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() 的值
等价操作
true val = std:: forward < U > ( v ) ;
false reinit-expected ( val , unex , std:: forward < U > ( v ) ) ;
has_val = false ;
4,5) 意外值的赋值操作如下:
重载版本
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 partial specialization assignment operators

6) 意外值的赋值或销毁规则如下:
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() 的值
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() 的值
等效操作
( 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 持有备选值(即从期望值转为非期望值,或从非期望值转为期望值)时被调用。

在此情况下,旧值 oldval 需要在新值 newval 构造前被销毁。然而, newval 的构造过程可能抛出异常。为了提供 强异常安全保证 ,需要在重新抛出异常前恢复旧值,以确保 * this 在异常处理期间保持有效状态。

返回值

1-9) * this

约束条件与补充信息

主模板赋值运算符

3) 此重载仅在满足以下所有条件时参与重载决议:
4) 此重载仅在以下所有值为 true 时参与重载决议:
5) 此重载仅在以下所有值为 true 时参与重载决议:

void 部分特化赋值运算符

6) 除非 std:: is_copy_assignable_v < E > std:: is_copy_constructible_v < E > 均为 true ,否则此重载被定义为已删除。
7) 仅当 std:: is_move_constructible_v < E > std:: is_move_assignable_v < E > 均为 true 时,此重载才会参与重载决议。
8) 此重载仅当 std:: is_constructible_v < E, const G & > std:: is_assignable_v < E & , const G & > 均为 true 时参与重载决议。
9) 此重载仅当 std:: is_constructible_v < E, G > std:: is_assignable_v < E & , G > 均为 true 时参与重载决议。

异常

示例

缺陷报告

下列行为变更缺陷报告被追溯应用于先前发布的C++标准。

缺陷报告 应用于 发布时的行为 正确行为
LWG 3886 C++23 重载版本 ( 3 ) 的默认模板参数是 T 改为 std:: remove_cv_t < T >
LWG 4025 C++23 E 不可移动构造或不可移动赋值时,
重载版本 ( 7 ) 被定义为已删除
在此情况下不参与
重载决议

参见

在原位构造期望值
(公开成员函数)