std::optional<T>::operator=
optional& operator=( std::nullopt_t ) noexcept; | (1) |
(начиная с C++17) (constexpr начиная с C++20) |
constexpr optional& operator=( const optional& other ); | (2) | (начиная с C++17) |
constexpr optional& operator=( optional&& other ) noexcept(/* see below */); | (3) | (начиная с C++17) |
template< class U = std::remove_cv_t<T> > optional& operator=( U&& value ); | (4) |
(начиная с C++17) (constexpr начиная с C++20) |
template< class U > optional& operator=( const optional<U>& other ); | (5) |
(начиная с C++17) (constexpr начиная с C++20) |
template< class U > optional& operator=( optional<U>&& other ); | (6) |
(начиная с C++17) (constexpr начиная с C++20) |
Заменяет содержимое *this содержимым other.
1) Если
2,3) Присваивает состояние *this содержит значение до вызова, содержащееся значение уничтожается вызовом его деструктора, как если бы был вызван value().T::~T(). После этого вызова *this не содержит значения.other. - Если ни
*this, ниotherне содержат значения, функция ничего не делает. - Если
*thisсодержит значение, аother— нет, содержащееся значение уничтожается вызовом его деструктора. После вызова*thisне содержит значения. - Если
otherсодержит значение, то в зависимости от того, содержит ли*thisзначение, содержащееся значение либо непосредственно инициализируется, либо ему присваивается значение из*other(2) илиstd::move(*other)(3). Обратите внимание: optional-объект после перемещения по-прежнему содержит значение. - Перегрузка (2) удалена, если
std::is_copy_constructible_v<T>илиstd::is_copy_assignable_v<T>являетсяfalse. Она тривиальна, еслиstd::is_trivially_copy_constructible_v<T>,std::is_trivially_copy_assignable_v<T>иstd::is_trivially_destructible_v<T>являютсяtrue. - Перегрузка (3) не участвует в разрешении перегрузки, если
std::is_move_constructible_v<T>илиstd::is_move_assignable_v<T>являетсяfalse. Она тривиальна, еслиstd::is_trivially_move_constructible_v<T>,std::is_trivially_move_assignable_v<T>иstd::is_trivially_destructible_v<T>являютсяtrue.
*this значение до вызова, содержащееся значение либо непосредственно инициализируется из std::forward<U>(value), либо ему присваивается значение из std::forward<U>(value). Функция не участвует в разрешении перегрузки, если std::decay_t<U>(до C++20)std::remove_cvref_t<U>(начиная с C++20) не является std::optional<T>, std::is_constructible_v<T, U> является true, std::is_assignable_v<T&, U> является true, и выполняется хотя бы одно из следующих условий: -
Tне является скалярным типом; -
std::decay_t<U>не являетсяT.
other. - Если ни
*this, ниotherне содержат значения, функция ничего не делает. - Если
*thisсодержит значение, аother— нет, содержащееся значение уничтожается вызовом его деструктора. После вызова*thisне содержит значения. - Если
otherсодержит значение, то в зависимости от того, содержит ли*thisзначение, содержащееся значение либо непосредственно инициализируется, либо ему присваивается значение из*other(5) илиstd::move(*other)(6). Обратите внимание: optional-объект после перемещения по-прежнему содержит значение. - Эти перегрузки не участвуют в разрешении перегрузки, если не выполнены следующие условия:
-
Tнельзя сконструировать, преобразовать или присвоить из выражения любого типа (возможно, const)std::optional<U>, то есть все следующие 12 характеристик типов имеют значениеfalse:std::is_constructible_v<T, std::optional<U>&>std::is_constructible_v<T, const std::optional<U>&>std::is_constructible_v<T, std::optional<U>&&>std::is_constructible_v<T, const std::optional<U>&&>std::is_convertible_v<std::optional<U>&, T>std::is_convertible_v<const std::optional<U>&, T>std::is_convertible_v<std::optional<U>&&, T>std::is_convertible_v<const std::optional<U>&&, T>std::is_assignable_v<T&, std::optional<U>&>std::is_assignable_v<T&, const std::optional<U>&>std::is_assignable_v<T&, std::optional<U>&&>std::is_assignable_v<T&, const std::optional<U>&&>
- Для перегрузки (5)
std::is_constructible_v<T, const U&>иstd::is_assignable_v<T&, const U&>имеют значениеtrue. - Для перегрузки (6)
std::is_constructible_v<T, U>иstd::is_assignable_v<T&, U>имеют значениеtrue.
-
Параметры
| other | - | другой объект optional, значение которого присваивается |
| value | - | значение, присваиваемое содержащемуся значению |
Возвращаемое значение
*this
Исключения
2-6) Выбрасывает любое исключение, выброшенное конструктором или оператором присваивания
T. Если выбрасывается исключение, состояние инициализации *this (и other в случае (2,3) и (5,6)) не изменяется, то есть если объект содержал значение, он по-прежнему его содержит, и наоборот. Содержимое value и значения, содержащиеся в *this и other, зависят от гарантий безопасности исключений операции, вызвавшей исключение (копирующий конструктор, перемещающее присваивание и т. д.).
3) Имеет следующую спецификацию
noexcept: noexcept(std::is_nothrow_move_assignable_v<T> && std::is_nothrow_move_constructible_v<T>)
Примечания
Объект optional op можно превратить в пустой optional с помощью op = {}; и op = nullopt;. Первое выражение создаёт пустой объект optional с помощью {} и присваивает его op.
| Макрос проверки поддержки возможностей | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_lib_optional | 202106L |
(C++20) (DR20) | Полностью constexpr (1), (4-6) |
Пример
#include <iostream>
#include <optional>
int main()
{
std::optional<const char*> s1 = "abc", s2; // constructor
s2 = s1; // assignment
s1 = "def"; // decaying assignment (U = char[4], T = const char*)
std::cout << *s2 << ' ' << *s1 << '\n';
}
Вывод:
abc def
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| Отчёт об ошибке | Применяется к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| LWG 3886 | C++17 | аргумент шаблона по умолчанию перегрузки (6) был T | изменён на std::remove_cv_t<T> |
| P0602R4 | C++17 | оператор копирующего/перемещающего присваивания мог быть нетривиальным даже если базовые операции тривиальны | требовалось сохранять тривиальность |
| P2231R1 | C++20 | операторы преобразующего присваивания (1) и (4-6) не были constexpr хотя необходимые операции могут быть такими в C++20 | сделаны constexpr |
См. также
| создаёт содержащееся значение на месте (открытая функция-член) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/utility/optional/operator%3D