名前空間
変種
操作

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

From cppreference.com
 
 
ユーティリティライブラリ
言語サポート
型のサポート (基本型、RTTI)
ライブラリ機能検査マクロ (C++20)
プログラムユーティリティ
可変引数関数
コルーチンサポート (C++20)
契約サポート (C++26)
三方比較
(C++20)
(C++20)(C++20)(C++20)  
(C++20)(C++20)(C++20)

汎用ユーティリティ
関係演算子 (C++20で非推奨)
 
 
プライマリテンプレート
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()の値が異なる場合(つまり、*thisotherのいずれかが期待値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 部分特殊化の代入演算子

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)
{
    // 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が代替値(つまり、期待値から期待値でない値へ、または期待値でない値から期待値へ)を持つようになる場合に呼び出されます。

この場合、新しい値newvalを構築する前に、古い値oldvalを破棄する必要があります。しかし、newvalの構築は例外をスローする可能性があります。強力な例外安全保証を提供するために、例外が再スローされる前に古い値を復元する必要があり、それにより、例外が処理されている間、*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
ムーブ構築可能またはムーブ代入可能でない
場合に
この場合、オーバーロード解決に参加しません。

[編集] 関連項目

期待値をインプレースで構築します。
(public member function) [編集]
English 日本語 中文(简体) 中文(繁體)