# std::optional<T>::operator=

< cpp‎ | utility‎ | optional

| (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 起)

以 `other` 的内容替换 *this 的内容。

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> 皆为 true 。若 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> 皆为 true 。若 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` 不可从任何 std::optional<U> 类型（可以为 const ）的表达式构造、转换、或赋值，即下列 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 （还有情况 (2-3) 和 (5-6) 的 `other` ）的初始化状态不改变，即若对象含值，则它仍然含值，反之亦然。 `value` 和 *this 及 `other` 所含有的值的内容依赖于异常来源操作（复制构造函数、移动构造函数等）的异常安全保证。
(3) 拥有下列
`noexcept` 说明：
noexcept(std::is_nothrow_move_assignable_v<T> && std::is_nothrow_move_constructible_v<T>)

### 注解

`optional` 对象 `op` 可以通过 op = {}; 和 op = nullopt; 变成空 `optional` 。第一个表达式以 {} 构造空的 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++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
P0602R4 | C++17 | 即使底层操作平凡，复制/移动赋值运算符亦可能不平凡 | 要求传播平凡性
P2231R1 | C++20 | 转换赋值运算符不是 constexpr 而要求的操作在 C++20 中能是 | 使之为 constexpr

### 参阅

emplace | 原位构造所含值 (公开成员函数)