std::optional<T>::operator=
来自cppreference.com
| (1) | (C++17 起) (C++20 起为 constexpr) |
|
| (2) | (C++17 起) | |
| |
(3) | (C++17 起) |
| (4) | (C++17 起) (C++20 起为 constexpr) |
|
| (5) | (C++17 起) (C++20 起为 constexpr) |
|
| (6) | (C++17 起) (C++20 起为 constexpr) |
|
以 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仍然**包含一个值**。 - 当
std::is_copy_constructible_v<T>或std::is_copy_assignable_v<T>为false时,重载 (2) 被弃置。如果std::is_trivially_copy_constructible_v<T>、std::is_trivially_copy_assignable_v<T>和std::is_trivially_destructible_v<T>均为true,则它是平凡的。 - 当
std::is_move_constructible_v<T>或std::is_move_assignable_v<T>为false时,重载 (3) 不参与重载决议。如果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(还有情况 (2-5) 的 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。
| 功能特性测试宏 | 值 | 标准 | 功能特性 |
|---|---|---|---|
__cpp_lib_optional |
202106L |
(C++20) (DR20) |
完全 constexpr (1), (4-6)
|
示例
运行此代码
#include <iostream>
#include <optional>
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++ 标准。
| 缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
|---|---|---|---|
| LWG 3886 | C++17 | 重载 (6) 的默认模板实参是 T
|
改成 std::remove_cv_t<T>
|
| P0602R4 | C++17 | 即使底层操作平凡,复制/移动赋值运算符亦可能不平凡 | 要求传播平凡性 |
| P2231R1 | C++20 | 重载 (1,4-6) 不是 constexpr 的
|
使之为 constexpr
|
参阅
| 原位构造所含值 (公开成员函数) |