std::optional
定义于头文件 <optional> |
||
template< class T > class optional; |
(C++17 起) | |
类模板 std::optional
管理一个可选的包含值,即一个可能存在也可能不存在的值。
optional
的一个常见用例是作为可能失败的函数的返回值。与其他方法(例如 std::pair<T, bool>)不同,optional
能够很好地处理构造开销大的对象,并且更具可读性,因为它明确表达了意图。
在任何给定时间,任何 optional
实例要么**包含一个值**,要么**不包含一个值**。
如果 optional
包含一个值,则该值保证**嵌套**在 optional
对象内部。因此,optional
对象模拟一个对象,而不是一个指针,尽管定义了 operator*() 和 operator->()。
当 optional
类型的对象被**上下文转换为 bool** 时,如果对象包含一个值,则转换返回 true;如果对象不包含值,则返回 false。
在以下情况下,optional
对象包含一个值:
- 对象使用类型为
T
的值或另一个包含值的optional
进行初始化/赋值。
在以下情况下,optional
对象不包含一个值:
- 对象被默认初始化。
- 对象使用类型为 std::nullopt_t 的值或不包含值的
optional
对象进行初始化/赋值。 - 调用了成员函数 reset()。
|
(C++26 起) |
不允许可选的引用、函数、数组或(可能带 cv 限定符的)void;如果实例化 optional
时使用此类类型,程序将是非良构的。此外,如果实例化 optional
时使用(可能带 cv 限定符的)标签类型 std::nullopt_t 或 std::in_place_t,程序也将是非良构的。
目录 |
[编辑] 模板参数
T | - | 要管理初始化状态的值的类型。该类型必须满足 可析构 的要求(特别是,不允许数组和引用类型)。 |
[编辑] 嵌套类型
类型 | 定义 |
value_type
|
T
|
iterator (C++26 起) |
实现定义的 旧式随机访问迭代器、常量表达式迭代器 和 连续迭代器 ,其 value_type 和 reference 分别是 std::remove_cv_t<T> 和 T&。 |
const_iterator (C++26 起) |
实现定义的 旧式随机访问迭代器、常量表达式迭代器 和 连续迭代器 ,其 value_type 和 reference 分别是 std::remove_cv_t<T> 和 const T&。 |
容器 的迭代器类型的所有要求也适用于 optional
的 iterator
类型。
[编辑] 数据成员
T* val |
指向包含对象(如果存在)的指针 (仅用于阐释的成员对象*) |
[编辑] 成员函数
构造 optional 对象(公共成员函数) | |
如果存在,销毁所包含的值 (公共成员函数) | |
赋值内容 (公共成员函数) | |
迭代器 | |
(C++26) |
返回指向起始的迭代器 (公共成员函数) |
(C++26) |
返回指向末尾的迭代器 (公共成员函数) |
观察器 | |
访问所包含的值 (公共成员函数) | |
检查对象是否包含值 (公共成员函数) | |
返回所包含的值 (公共成员函数) | |
如果可用,返回包含的值,否则返回另一个值 (公共成员函数) | |
Monadic operations | |
(C++23) |
如果存在包含的值,则返回给定函数对该值的结果,否则返回空的 optional (公共成员函数) |
(C++23) |
如果存在包含的值,则返回一个包含转换后的值的 optional ,否则返回一个空的 optional (公共成员函数) |
(C++23) |
如果 optional 包含值,则返回 optional 本身,否则返回给定函数的结果(公共成员函数) |
修改器 | |
交换内容 (公共成员函数) | |
销毁任何包含的值 (公共成员函数) | |
就地构造包含的值 (公共成员函数) |
[编辑] 非成员函数
(C++17)(C++17)(C++17)(C++17)(C++17)(C++17)(C++20) |
比较 optional 对象(函数模板) |
(C++17) |
创建 optional 对象(函数模板) |
(C++17) |
特化 std::swap 算法 (函数模板) |
[编辑] 辅助类
(C++17) |
对 std::optional 的哈希支持 (类模板特化) |
(C++17) |
指示 std::optional 不包含值的类型(类) |
(C++17) |
当检查式访问不包含值的 optional 时抛出的异常 (类) |
[编辑] 辅助函数
(C++17) |
nullopt_t 类型的对象(常量) |
原地构造标签 (标签) |
[编辑] 辅助特化
template< class T > constexpr bool ranges::enable_view<std::optional<T>> = true; |
(C++26 起) | |
此 ranges::enable_view 特化使得 optional
满足 view
的要求。
template< class T > constexpr auto format_kind<std::optional<T>> = range_format::disabled; |
(C++26 起) | |
此 format_kind 特化禁用 optional
的 范围格式化支持。
[编辑] 推导指南
[编辑] 备注
特性测试宏 | 值 | 标准 | 特性 |
---|---|---|---|
__cpp_lib_optional |
201606L |
(C++17) | std::optional
|
202106L |
(C++23) (DR20) |
完全 constexpr | |
202110L |
(C++23) | Monadic operations | |
__cpp_lib_optional_range_support |
202406L |
(C++26) | 对 std::optional 的范围支持 |
[编辑] 示例
#include <iostream> #include <optional> #include <string> // optional can be used as the return type of a factory that may fail std::optional<std::string> create(bool b) { if (b) return "Godzilla"; return {}; } // std::nullopt can be used to create any (empty) std::optional auto create2(bool b) { return b ? std::optional<std::string>{"Godzilla"} : std::nullopt; } int main() { std::cout << "create(false) returned " << create(false).value_or("empty") << '\n'; // optional-returning factory functions are usable as conditions of while and if if (auto str = create2(true)) std::cout << "create2(true) returned " << *str << '\n'; }
输出
create(false) returned empty create2(true) returned Godzilla
[编辑] 缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 发布时的行为 | 正确的行为 |
---|---|---|---|
LWG 4141 | C++17 | 存储要求 令人困惑 |
包含的对象必须 嵌套在 optional 对象中 |
[编辑] 参阅
(C++17) |
一种类型安全的带判别联合体 (类模板) |
(C++17) |
保存任意 可复制构造 类型实例的对象 (类) |
(C++23) |
一个包装器,包含预期值或错误值 (类模板) |
一个包含单个指定值的 view (类模板) (自定义点对象) | |
一个不含元素的空 view (类模板) (变量模板) |