Namespaces
Variants

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

From ru.cppreference.net
 
 
Библиотека утилит
Поддержка языка
Поддержка типов (основные типы, 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(/*see below*/);
(2) (начиная с C++23)
template< class U = std::remove_cv_t<T> >
constexpr expected& operator=( U&& v );
(3) (начиная с C++23)
(T не является cv void)
template< class G >
constexpr expected& operator=( const unexpected<G>& other );
(4) (начиная с C++23)
template< class G >
constexpr expected& operator=( unexpected<G>&& other );
(5) (начиная с C++23)

Присваивает новое значение существующему объекту expected.

1,2) Присваивает состояние объекта other.
  • Если this->has_value() равно other.has_value(), присваивает значение, содержащееся в other. Ничего не делает, если T является (возможно, cv-квалифицированным) void и other.has_value() является true.
  • В противном случае уничтожает текущее содержащееся значение (ничего не делает, если this->has_value() является true и T является (возможно, cv-квалифицированным) void), и делает так, чтобы *this содержал копию значения, содержащегося в other.
Если other.has_value() является true и T является (возможно, cv-квалифицированным) void, не конструирует новое значение. В противном случае новое значение конструируется копированием (1) или перемещением (2) из *other или other.error(), в зависимости от ситуации. Если возникает исключение, старое значение сохраняется; *this не становится беззначным.

Если исключение не было выброшено, после присваивания has_value() равно other.has_value().

  • Перегрузка (1) определена как удалённая, если только
    • либо T является (возможно, cv-квалифицированным) void или std::is_copy_assignable_v<T> является true, и
    • либо T является (возможно, cv-квалифицированным) void или std::is_copy_constructible_v<T> является true, и
    • std::is_copy_assignable_v<E> является true, и
    • std::is_copy_constructible_v<E> является true, и
    • по меньшей мере одно из следующих условий является true:
      • T является (возможно, cv-квалифицированным) void
      • std::is_nothrow_move_constructible_v<T>
      • std::is_nothrow_move_constructible_v<E>
  • Перегрузка (2) участвует в разрешении перегрузки только если
    • либо T является (возможно, cv-квалифицированным) void или std::is_move_assignable_v<T> является true, и
    • либо T является (возможно, cv-квалифицированным) void или std::is_move_constructible_v<T> является true, и
    • std::is_move_assignable_v<E> является true, и
    • std::is_move_constructible_v<E> является true, и
    • по меньшей мере одно из следующих условий является true:
      • T является (возможно, cv-квалифицированным) void
      • std::is_nothrow_move_constructible_v<T>
      • std::is_nothrow_move_constructible_v<E>
3) Присваивает из ожидаемого значения.
  • Если this->has_value() является true, эквивалентно **this = std::forward<U>(v).
  • В противном случае уничтожает значение, содержащееся в *this, и делает так, чтобы *this содержал значение, инициализированное из std::forward<U>(v). Если возникает исключение, старое значение сохраняется; *this не становится беззначным.

Если исключение не было выброшено, после присваивания this->has_value() является true.

  • Эта перегрузка участвует в разрешении перегрузки только если
    • std::is_same_v<expected, std::remove_cvref_t<U>> является false, и
    • std::remove_cvref_t<U> не является специализацией std::unexpected, и
    • std::is_constructible_v<T, U> является true, и
    • std::is_assignable_v<T&, U> является true, и
    • по меньшей мере одно из следующих условий является true:
      • std::is_nothrow_constructible_v<T, U>
      • std::is_nothrow_move_constructible_v<T>
      • std::is_nothrow_move_constructible_v<E>
4,5) Присваивает из неожиданного значения.

Пусть GF будет const G& для перегрузки (4), и G для перегрузки (5).

  • Если this->has_value() является true, уничтожает значение, содержащееся в *this (ничего не делает, если T является (возможно, cv-квалифицированным) void), и делает так, чтобы *this содержал значение, инициализированное из std::forward<GF>(e.error()). Если возникает исключение, старое значение сохраняется; *this не становится беззначным.
  • В противном случае эквивалентно this->error() = std::forward<GF>(e.error()).

Если исключение не было выброшено, после присваивания this->has_value() является false.

  • Эта перегрузка участвует в разрешении перегрузки только если
    • std::is_constructible_v<E, GF> является true, и
    • std::is_assignable_v<E&, GF> является true, и
    • по меньшей мере одно из следующих условий является true:
      • T является (возможно, cv-квалифицированным) void
      • std::is_nothrow_constructible_v<E, GF>
      • std::is_nothrow_move_constructible_v<T>
      • std::is_nothrow_move_constructible_v<E>


Во всех случаях, если T не является (возможно, cv-квалифицированным) void, уничтожение старого значения и конструирование нового выполняются так, как если бы с помощью следующей функции reinit_expected (только для демонстрации).

template<class NewType, class OldType, class... Args>
constexpr void reinit_expected(NewType& new_val, OldType& old_val, Args&&... args)
{
    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)...);
    }
    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));
    }
    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)...); // may throw
        }
        catch (...)
        {
            std::construct_at(std::addressof(old_val), std::move(temp));
            throw;
        }
    }
}

Параметры

other - другой expected объект, чьё содержащееся значение нужно присвоить
v - значение для присваивания содержащемуся значению
e - std::unexpected объект, чьё содержащееся значение нужно присвоить
newval - содержащееся значение для конструирования
oldval - содержащееся значение для уничтожения
args - аргументы, используемые как инициализаторы newval

Возвращаемое значение

1-9) * this

Исключения

Пример

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
LWG 3886 C++23 аргумент шаблона по умолчанию для перегрузки ( 3 ) был T изменён на std:: remove_cv_t < T >
LWG 4025 C++23 перегрузка ( 7 ) была определена как удалённая, если E не является
перемещаемо конструируемым или не перемещаемо присваиваемой
она не участвует в
разрешении перегрузки в этом случае

Смотрите также

создаёт ожидаемое значение на месте
(публичная функция-член)