std::expected<T,E>::operator=
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.
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>
-
- либо
- Если
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>
-
Пусть 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, значение которого требуется присвоить |
| value | - | значение, присваиваемое содержащемуся значению |
| e | - |
объект std::unexpected, значение которого требуется присвоить |
Возвращаемое значение
*this
Исключения
T или E.T является (возможно, cv-квалифицированным) void, noexcept спецификация: noexcept(std::is_nothrow_move_constructible_v<E> && std::is_nothrow_move_assignable_v<E>)
noexcept спецификация: noexcept(
std::is_nothrow_move_constructible_v<T> && std::is_nothrow_move_assignable_v<T> &&
std::is_nothrow_move_constructible_v<E> && std::is_nothrow_move_assignable_v<E>)
T.E.Пример
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| Отчёт об ошибке | Применён к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| LWG 3886 | C++23 | аргумент шаблона по умолчанию перегрузки (3) был T | изменён на std::remove_cv_t<T> |
| LWG 4025 | C++23 | перемещающее присваивание (2) для std::expected<void, E>определялось как удалённое, если E не поддерживает перемещающее конструирование или перемещающее присваивание | в этом случае оно не участвует в разрешении перегрузки |
См. также
| конструирует значение expected на месте (открытая функция-член) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/utility/expected/operator%3D