std::optional<T>:: optional
|
constexpr
optional
(
)
noexcept
;
|
(1) | (自 C++17 起) |
|
constexpr
optional
(
std::
nullopt_t
)
noexcept
;
|
(2) | (自 C++17 起) |
|
constexpr
optional
(
const
optional
&
other
)
;
|
(3) | (自 C++17 起) |
|
constexpr
optional
(
optional
&&
other
)
noexcept
(
/* 见下文 */
)
;
|
(4) | (自 C++17 起) |
|
template
<
class
U
>
optional ( const optional < U > & other ) ; |
(5) |
(自 C++17 起)
(自 C++20 起为 constexpr) (条件性显式) |
|
template
<
class
U
>
optional ( optional < U > && other ) ; |
(6) |
(自 C++17 起)
(自 C++20 起为 constexpr) (条件性显式) |
|
template
<
class
...
Args
>
constexpr explicit optional ( std:: in_place_t , Args && ... args ) ; |
(7) | (自 C++17 起) |
|
template
<
class
U,
class
...
Args
>
constexpr
explicit
optional
(
std::
in_place_t
,
|
(8) | (自 C++17 起) |
|
template
<
class
U
=
std::
remove_cv_t
<
T
>
>
constexpr optional ( U && value ) ; |
(9) |
(自 C++17 起)
(条件性显式) |
构造一个新的
optional
对象。
目录 |
参数
| other | - |
另一个
optional
对象,其包含的值将被复制
|
| value | - | 用于初始化所包含值的值 |
| args... | - | 用于初始化所包含值的参数 |
| ilist | - | 用于初始化所包含值的初始化列表 |
效果
| 重载版本 | 初始化方式 | 所含值的初始化器 |
构造后
has_value()
状态
|
|---|---|---|---|
| ( 1 ) | 不适用 | - | false |
| ( 2 ) | |||
| ( 3 ) | 直接初始化 (非列表) | * other |
other.
has_value
(
)
|
| ( 4 ) | std :: move ( * other ) | ||
| ( 5 ) | * other | ||
| ( 6 ) | std :: move ( * other ) | ||
| ( 7 ) | std:: forward < Args > ( args ) ... | true | |
| ( 8 ) | ilist, std:: forward < Args > ( args ) ... | ||
| ( 9 ) | std:: forward < U > ( value ) |
约束条件与补充信息
- std:: is_constructible_v < T, const U & > 为 true 。
-
若
T不是(可能带有 cv 限定符的) bool ,则以下 8 个值均为 false [1] :- 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_constructible_v < T, U > 为 true 。
-
若
T不是(可能带 cv 限定符的) bool ,则以下 8 个值均为 false [1] :- 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 >
T
的构造函数是
constexpr
构造函数,则该构造函数也是
constexpr
构造函数。
T
的构造函数是
constexpr
构造函数,则该构造函数也是
constexpr
构造函数。
- std:: is_constructible_v < T, U > 为 true 。
- std:: decay_t < U > (C++20 前) std:: remove_cvref_t < U > (C++20 起) 既不是 std::in_place_t 也不是 std:: optional < T > 。
-
若
T为(可能带 cv 限定符的) bool ,则 std:: decay_t < U > (C++20 前) std:: remove_cvref_t < U > (C++20 起) 不是std::optional的特化。
T
的构造函数是
constexpr
构造函数,则该构造函数也是
constexpr
构造函数。
-
↑
1.0
1.1
换言之,
T既不可构造也不可从任何类型为(可能 const 限定的) std:: optional < U > 的表达式转换而来
异常
T
的构造函数抛出的任何异常。
T
的构造函数抛出的任何异常。具有以下
T
的构造函数抛出的任何异常。
推导指引
注释
在
LWG 问题 3836
解决之前,从
std::
optional
<
U
>
构造
std::
optional
<
bool
>
时,若
U
不是
bool
类型,会选择重载
(
9
)
而非重载
(
5,6
)
。这是因为当
T
(此处为
bool
)可从
std::
optional
<
U
>
构造或转换时,重载
(
5,6
)
不参与重载决议,而
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); // 正确:包含值0(从false初始化) std::optional<bool> from_int(op_zero); // 缺陷(LWG 3836):包含true,因为 // op_zero包含有效值,即使从该值 // 初始化bool类型会得到false
| 功能测试 宏 | 值 | 标准 | 功能特性 |
|---|---|---|---|
__cpp_lib_optional
|
202106L
|
(C++20)
(DR20) |
完全 constexpr 化 ( 5,6 ) |
示例
#include <iostream> #include <optional> #include <string> int main() { std::optional<int> o1, // 空值 o2 = 1, // 从右值初始化 o3 = o2; // 拷贝构造函数 // 调用 std::string( initializer_list<CharT> ) 构造函数 std::optional<std::string> o4(std::in_place, {'a', 'b', 'c'}); // 调用 std::string( size_type count, CharT ch ) 构造函数 std::optional<std::string> o5(std::in_place, 3, 'A'); // 使用推导指南从 std::string 移动构造 std::optional o6(std::string{"deduction"}); std::cout << *o2 << ' ' << *o3 << ' ' << *o4 << ' ' << *o5 << ' ' << *o6 << '\n'; }
输出:
1 1 abc AAA deduction
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的C++标准。
| 缺陷报告 | 应用于 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| LWG 3836 | C++17 |
当从
std::
optional
<
U
>
构造
std::
optional
<
bool
>
时,
若
U
不是
bool
则会选择重载
(
9
)
|
在此情况下始终选择
转换复制/移动构造函数 |
| LWG 3886 | C++17 |
重载
(
9
)
的默认模板参数为
T
|
改为 std:: remove_cv_t < T > |
| P0602R4 | C++17 |
即使底层构造函数是平凡的,
复制/移动构造函数也可能不是平凡的 |
要求传播
平凡性 |
| P2231R1 | C++20 |
来自其他
std::optional
的重载
(
5,6
)
不是
constexpr
|
改为 constexpr |
参见
|
(C++17)
|
创建
optional
对象
(函数模板) |