Spec-Zone.ru › C++

std::optional<T>::operator=

(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(/* see below */);
(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 <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++.

DR Применено к Поведение, как опубликовано Правильное поведение
P0602R4 C++17 Оператор копирования/перемещения присваивания может не быть тривиальным
даже если подлежащие операции тривиальны
требовалось распространять тривиальность
P2231R1 C++20 Конвертирующие операторы присваивания не были constexpr,
в то время как необходимые операции могут быть в C++20
сделаны constexpr

См. также

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

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

Spec-Zone.ru

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