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 ( /* 下記参照 */ ) ;
(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 の一方が期待値を含み、他方が非期待値を含む場合)、説明専用の関数テンプレート 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 部分特殊化代入演算子

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 が代替値を保持するようになる場合(すなわち、expected値からunexpected値へ、またはunexpected値からexpected値へ変更される場合)に呼び出されます。

この場合、古い値 oldval は新しい値 newval の構築前に破棄される必要があります。しかし、 newval の構築は例外をスローする可能性があります。 strong exception safety guarantee を提供するためには、例外を再スローする前に古い値を復元する必要があり、これにより例外処理中も * this が有効な状態を維持します。

戻り値

1-9) * this

制約条件と補足情報

プライマリテンプレート代入演算子

1) 以下のすべての値が true でない限り、このオーバーロードは削除定義されます:
2) このオーバーロードは、以下のすべての値が true である場合にのみ、オーバーロード解決に参加します:
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++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
LWG 3886 C++23 オーバーロード ( 3 ) のデフォルトテンプレート引数は T であった std:: remove_cv_t < T > に変更
LWG 4025 C++23 オーバーロード ( 7 ) E がムーブ構築可能でないか
ムーブ代入可能でない場合に削除定義されていた
この場合、オーバーロード解決に
参加しない

関連項目

期待される値をその場で構築する
(公開メンバ関数)