C++ std::optional 详解
1、什么是 std::optional?
std::optional 是 C++17 引入的一个模板类,它用于表示一个 可能包含值,也可能不包含值(即为'空') 的封装。它提供了一种类型安全、表达清晰的方式来处理那些不总是有有效结果的操作(比如查找、解析、计算等)。
- 核心思想:一个
std::optional<T>对象要么持有一个类型为T的值,要么什么都不持有(表示为std::nullopt)。 - 替代方案:在引入
std::optional之前,通常使用特殊值(如-1,nullptr,std::string::npos)、bool标志位加一个值变量、或返回指针(可能为nullptr)等方式来表示可选值。std::optional提供了一种更标准、更安全、更易于理解的方式。
2、为什么需要 std::optional?
- 类型安全:明确区分有值和无值的状态,编译器可以检查,避免误用无效值。
- 表达清晰:代码意图更明确,看到
std::optional就知道这个值可能不存在。 - 避免魔术值:不再需要使用特定的、有时难以记忆或容易混淆的'无效值'来表示缺失。
- 更好的接口设计:函数可以清晰地返回一个可能不存在的结果,而不是通过输出参数或异常(在某些场景下异常可能太重)来传递状态。
- 效率:通常,
std::optional<T>的内存占用是sizeof(T) + sizeof(bool)加上可能的对齐填充。它通常比使用动态内存分配(如std::unique_ptr)更轻量。
3、核心操作与成员函数
3.1、构造与赋值
- 拷贝/移动构造与赋值:支持从另一个
optional拷贝或移动。
赋值:可以使用 = 来赋值一个值、std::nullopt 或另一个 optional。
optInt = 42; // 现在包含 42
optInt = std::nullopt; // 变为空
std::in_place 构造:用于直接原地构造包含的对象,特别是当 T 的构造函数需要多个参数,或者你想避免临时对象时。
std::optional<std::complex<double>> optComplex(std::in_place, 1.0, 2.0); // 构造 complex(1.0, 2.0)
值初始化:用给定的值构造一个包含该值的 optional。



