Spec-Zone.ru › C++

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) Если *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.

Макрос проверки поддержки возможностей Значение Стандарт Возможность
__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

См. также

emplace
создаёт содержащееся значение на месте
(открытая функция-член)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/utility/optional/operator%3D

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API