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 ( /* см. ниже */ ) ;
(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) Содержащееся значение присваивается следующим образом:
Значение
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" не выбрасывает исключения:
    // "new_val" может быть напрямую сконструирован после уничтожения "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)...);
    }
    // Случай 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

Ограничения и дополнительная информация

Основные операторы присваивания шаблона

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 не является
перемещаемо конструируемым или не перемещаемо присваиваемой
она не участвует в
разрешении перегрузки в этом случае

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

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