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<T> 型別的物件被語境轉換為 bool 時,若該物件包含一個值,則轉換回傳 true,若不包含值則回傳 false。
optional 物件在下列條件下包含一個值:
- 該物件是使用
T型別的值或另一個包含值的optional進行初始化或指派而來。
該物件在下列條件下不包含值:
- 該物件是預設初始化的。
- 該物件是使用 std::nullopt_t 型別的值或一個不包含值的
optional物件進行初始化或指派而來。 - 呼叫了成員函式 reset()。
|
|
(C++26 起) |
不存在選用參照、函式、陣列或(可能帶有 cv 限定符的)void;若程式以這類型別實例化 optional,則該程式為非法形式 (ill-formed)。此外,若程式以(可能帶有 cv 限定符的)標籤型別 std::nullopt_t 或 std::in_place_t 實例化 optional,該程式亦為非法形式。
目錄 |
[編輯] 範本參數
| T | - | 欲管理初始化狀態的值之型別。該型別必須符合 Destructible 的要求(特別是,不允許陣列和參照型別)。 |
[編輯] 巢狀型別
| 類型 | 定義 |
value_type
|
T
|
iterator (自 C++26 起) |
實作定義的 LegacyRandomAccessIterator、ConstexprIterator 與 contiguous_iterator,其 value_type 和 reference 分別為 std::remove_cv_t<T> 與 T&。 |
const_iterator (自 C++26 起) |
實作定義的 LegacyRandomAccessIterator、ConstexprIterator 與 contiguous_iterator,其 value_type 和 reference 分別為 std::remove_cv_t<T> 與 const T&。 |
所有對 Container 迭代器型別的要求,同樣適用於 optional 的 iterator 型別。
[編輯] 資料成員
T* val |
指向所包含物件的指標(若存在) (僅用於闡述的成員物件*) |
[編輯] 成員函式
建構 optional 物件(公開成員函式) | |
| 銷毀包含的值 (如果存在) (公開成員函式) | |
| 賦值內容 (公開成員函式) | |
迭代器 | |
| (C++26) |
回傳指向起點的反覆器 (公開成員函式) |
| (C++26) |
回傳指向終點的反覆器 (公開成員函式) |
觀察器 | |
| 存取包含的值 (公開成員函式) | |
| 檢查物件是否包含值 (公開成員函式) | |
| 回傳所包含的值 (公開成員函式) | |
| 若可用則回傳所包含的值,否則回傳另一個值 (公開成員函式) | |
單子 (Monadic) 操作 | |
| (C++23) |
若值存在,則回傳對該包含值呼叫指定函式的結果,否則回傳一個空的 optional(公開成員函式) |
| (C++23) |
若值存在,則回傳包含轉換後之值的 optional,否則回傳一個空的 optional(公開成員函式) |
| (C++23) |
若包含值則回傳該 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) 操作 | |
__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++ 標準。
| DR | 應用於 | 出版時的行為 | 正確的行為 |
|---|---|---|---|
| LWG 4141 | C++17 | 關於儲存的需求 配置 (allocation) 描述易造成混淆 |
所包含的物件必須 嵌套於 optional 物件中 |
[編輯] 參見
| (C++17) |
一種型別安全的識別聯合體 (discriminated union) (類別模板) |
| (C++17) |
持有任何 CopyConstructible 型別實例的物件 (類別) |
| (C++23) |
包含預期值或錯誤值的封裝器 (類別範本) |
包含指定值的單一元素的 view(類別範本) (自定義點物件) | |
一個不含元素的空 view(類別範本) (變數範本) |