std::optional<T>::operator=
Материал из cppreference.com
<tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
| (1) | ||
optional& operator=( std::nullopt_t ) noexcept; |
(начиная с C++17) (до C++20) |
|
constexpr optional& operator=( std::nullopt_t ) noexcept; |
(начиная с C++20) | |
constexpr optional& operator=( const optional& other ); |
(2) | (начиная с C++17) |
constexpr optional& operator=( optional&& other ) noexcept(/* смотрите ниже */); |
(3) | (начиная с C++17) |
| (4) | ||
template< class U = T > optional& operator=( U&& value ); |
(начиная с C++17) (до C++20) |
|
template< class U = T > constexpr optional& operator=( U&& value ); |
(начиная с C++20) | |
| (5) | ||
template< class U > optional& operator=( const optional<U>& other ); |
(начиная с C++17) (до C++20) |
|
template< class U > constexpr optional& operator=( const optional<U>& other ); |
(начиная с C++20) | |
| (6) | ||
template< class U > optional& operator=( optional<U>&& other ); |
(начиная с C++17) (до C++20) |
|
template< class U > constexpr optional& operator=( optional<U>&& other ); |
(начиная с C++20) | |
Заменяет содержимое *this содержимым other
1) Если
*this содержит значение перед вызовом, содержащееся в нём значение уничтожается вызовом его деструктора, как будто value().T::~T(). *this не содержит значения после этого вызова.2,3) Присваивает состояние
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.
4) Присваивание с полной пересылкой: в зависимости от того, содержит ли
*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.
5,6) Присваивает состояние
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.
Пример
Запустить этот код
#include <optional>
#include <iostream>
int main()
{
std::optional<const char*> s1 = "abc", s2; // конструктор
s2 = s1; // присваивание
s1 = "def"; // разрушающее присваивание (U = char[4], T = const char*)
std::cout << *s2 << ' ' << *s1 << '\n';
}
Вывод:
abc def
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| WG не указан | C++17 | оператор присваивания копированием/перемещением может быть нетривиальным, даже если базовые операции тривиальны |
требуется для распространения тривиальности |
| WG не указан | C++20 | преобразующие операторы присваивания не были constexpr, в то время как необходимые операции могут быть в C++20 |
сделаны constexpr |
Смотрите также
| создаёт содержащееся значение на месте (public функция-элемент) |