命名空间
变体
操作

std::optional<T>::optional

来自 cppreference.com
< cpp‎ | utility‎ | optional
 
 
实用程序库
语言支持
类型支持 (基本类型,RTTI)
库特性测试宏 (C++20)
动态内存管理
程序实用程序
协程支持 (C++20)
可变参数函数
调试支持
(C++26)
三元比较
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
通用实用程序
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中已弃用)
整数比较函数
(C++20)(C++20)(C++20)   
(C++20)
交换类型操作
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
通用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
基本字符串转换
(C++17)
(C++17)

 
 
constexpr optional() noexcept;
constexpr optional( std::nullopt_t ) noexcept;
(1) (自 C++17 起)
constexpr optional( const optional& other );
(2) (自 C++17 起)
constexpr optional( optional&& other ) noexcept(/* 见下文 */);
(3) (自 C++17 起)
template < class U >
optional( const optional<U>& other );
(4) (自 C++17 起)
(自 C++20 起为 constexpr)
(条件显式)
template < class U >
optional( optional<U>&& other );
(5) (自 C++17 起)
(自 C++20 起为 constexpr)
(条件显式)
template< class... Args >
constexpr explicit optional( std::in_place_t, Args&&... args );
(6) (自 C++17 起)
template< class U, class... Args >

constexpr explicit optional( std::in_place_t,
                             std::initializer_list<U> ilist,

                             Args&&... args );
(7) (自 C++17 起)
template < class U = T >
constexpr optional( U&& value );
(8) (自 C++17 起)
(条件显式)

构造一个新的 optional 对象。

1) 构造一个不包含值的 optional 对象。
2) 复制构造函数:如果other包含值,则初始化包含的值,就好像直接初始化(但不是直接列表初始化)类型为T的对象,其表达式为*other。如果other不包含值,则构造一个不包含值的 optional 对象。
3) 移动构造函数:如果other包含值,则初始化包含的值,就好像直接初始化(但不是直接列表初始化)类型为T的对象,其表达式为std::move(*other),并且不会使other为空:移动后的std::optional仍然包含值,但值本身已移动。
4) 转换复制构造函数:如果other不包含值,则构造一个不包含值的 optional 对象。否则,构造一个包含值的 optional 对象,就好像直接初始化(但不是直接列表初始化)类型为T的对象,其表达式为*other
5) 转换移动构造函数:如果 other 不包含值,则构造一个不包含值的可选对象。否则,构造一个包含值的可选对象,初始化方式与使用 直接初始化(但不是直接列表初始化)类型为 `T` 的对象时使用表达式 std::move(*other) 相同。
6) 构造一个包含值的可选对象,初始化方式与使用 直接初始化(但不是直接列表初始化)类型为 `T` 的对象时使用参数 std::forward<Args>(args)... 相同。
  • 如果 `T` 的选定构造函数是 constexpr 构造函数,则此构造函数是 constexpr 构造函数。
  • 除非 std::is_constructible_v<T, Args...>true,否则该函数不参与重载解析。
7) 构造一个包含值的可选对象,初始化方式与使用 直接初始化(但不是直接列表初始化)类型为 `T` 的对象时使用参数 ilist, std::forward<Args>(args)... 相同。
  • 如果 `T` 的选定构造函数是 constexpr 构造函数,则此构造函数是 constexpr 构造函数。
  • 除非 std::is_constructible_v<T, std::initializer_list<U>&, Args...>true,否则该函数不参与重载解析。
8) 构造一个包含值的可选对象,初始化方式与使用 直接初始化(但不是直接列表初始化)类型为 `T` 的对象时使用表达式 std::forward<U>(value) 相同。

内容

[edit] 参数

other - 另一个可选对象,其包含的值被复制
value - 用于初始化包含值的 value
args... - 用于初始化包含值的 arguments
ilist - 用于初始化包含值的 initializer list

[edit] 异常

2) 抛出 `T` 构造函数抛出的任何异常。
3) 抛出 `T` 构造函数抛出的任何异常。具有以下
noexcept 规范:  
4-8) 抛出 `T` 构造函数抛出的任何异常。

[edit] 推导指南

[edit] 注释

在解决 LWG issue 3836 之前,从 std::optional<U> 构造 std::optional<bool> 将选择重载 (8) 而不是重载 (4,5),如果 `U` 不是 bool。这是因为如果 `T`(在本例中为 bool)可以从 std::optional<U> 构造或转换,则重载 (4,5) 不参与重载解析,但 std::optional::operator bool 使得对于任何 `U` 转换成为可能。

结果,构造的 std::optional<bool> 始终包含一个值。该值取决于提供的 std::optional<U> 对象是否包含一个值,而不是直接从包含的值直接初始化的 bool 值。

std::optional<bool> op_false(false);
std::optional<int> op_zero(0);
 
std::optional<int> from_bool(op_false); // OK: contains 0 (initialized from false)
std::optional<bool> from_int(op_zero);  // DEFECT (LWG 3836): contains true because
                                        // op_zero contains a value, even if initializing
                                        // bool from that value gives false
特性测试 Std 特性
__cpp_lib_optional 202106L (C++20)
(DR20)
完全 constexpr (4,5)

[编辑] 示例

#include <iostream>
#include <optional>
#include <string>
 
int main()
{
    std::optional<int> o1, // empty
                       o2 = 1, // init from rvalue
                       o3 = o2; // copy-constructor
 
    // calls std::string( initializer_list<CharT> ) constructor
    std::optional<std::string> o4(std::in_place, {'a', 'b', 'c'});
 
    // calls std::string( size_type count, CharT ch ) constructor
    std::optional<std::string> o5(std::in_place, 3, 'A');
 
    // Move-constructed from std::string using deduction guide to pick the type
 
    std::optional o6(std::string{"deduction"});
 
    std::cout << *o2 << ' ' << *o3 << ' ' << *o4 << ' ' << *o5  << ' ' << *o6 << '\n';
}

输出

1 1 abc AAA deduction

[编辑] 缺陷报告

以下行为更改的缺陷报告被追溯应用到先前发布的 C++ 标准。

DR 应用于 已发布的行为 正确行为
LWG 3836 C++17 当构造一个 std::optional<bool>
std::optional<U>,重载解析
将选择重载 (8) 如果 U 不是 bool
总是选择
转换复制/移动
在这种情况下构造函数
P0602R4 C++17 复制/移动构造函数可能不是平凡的
即使底层构造函数是平凡的
需要
传播平凡性
P2231R1 C++20 从另一个 std::optional 进行转换构造 (4,5)
constexpr 虽然所需的操作可以在 C++20 中
变为 constexpr

[编辑] 参见

创建一个 optional 对象
(函数模板) [编辑]