std::experimental::scope_fail
出自 cppreference.com
< cpp | experimental
| 定義於標頭檔 <experimental/scope> |
||
| template< class EF > class scope_fail; |
(library fundamentals TS v3) | |
類別模板 scope_fail 是一種通用的作用域防護(scope guard),旨在當作用域因異常而退出時呼叫其離開函數(exit function)。
scope_fail 不具備 CopyConstructible(可複製建構)、CopyAssignable(可複製賦值)或 MoveAssignable(可移動賦值)特性。然而,若 EF 符合特定要求,它可以是 MoveConstructible(可移動建構),這允許將 scope_fail 封裝至另一個物件中。
scope_fail 可以是「啟用」狀態(即在解構時呼叫其離開函數)或「停用」狀態(即在解構時不做任何事)。scope_fail 在由離開函數建構後即處於啟用狀態。
透過手動呼叫 release() 或自動(透過移動建構子)呼叫,scope_fail 可以變為停用狀態。使用另一個已停用的 scope_fail 進行初始化亦可獲得已停用的 scope_fail。一旦 scope_fail 變為停用狀態,它便無法再次變回啟用狀態。
一個 scope_fail 實際上持有一個 EF 和一個用來指示其是否啟用的 bool 旗標,以及一個用於檢測解構子是否在堆疊展開(stack unwinding)期間被呼叫的未捕獲異常計數器。
目錄 |
[edit] 模板參數
| EF | - | 所儲存的結束函式類型 |
| 類型要求 | ||
-EF 必須是下列其中之一:
| ||
| -以無參數形式呼叫 std::remove_reference_t<EF> 的左值必須是良構(well-formed)的。 | ||
[edit] 成員函式
建構一個新的 scope_fail(公開成員函式) | |
若 scope_fail 處於啟用狀態,則在作用域因異常而退出時呼叫離開函數,隨後銷毀該 scope_fail(公開成員函式) | |
| operator= [已刪除] |
scope_fail 不可賦值(公開成員函式) |
修改器 | |
使 scope_fail 變為停用狀態(公開成員函式) | |
[編輯] 推導指引
[edit] 附註
建構具有動態儲存期的 scope_fail 可能會導致非預期的行為。
若 scope_fail 是從另一個在不同執行緒中建立的 scope_fail 建構而來,也可能導致非預期的行為,因為在解構期間可能會比較不同執行緒中獲得的未捕獲異常計數。
[edit] 範例
執行此程式碼
#include <iostream> #include <cstdlib> #include <string_view> #include <experimental/scope> void print_exit_status(std::string_view name, bool exit_status, bool did_throw) { std::cout << name << ":\n"; std::cout << " Throwed exception " << (did_throw ? "yes" : "no") << "\n"; std::cout << " Exit status " << (exit_status ? "finished" : "pending") << "\n\n"; } // Randomly throw an exception (50% chance) void maybe_throw() { if (std::rand() >= RAND_MAX / 2) throw std::exception{}; } int main() { bool exit_status{false}, did_throw{false}; // Manual handling at "end of scope" try { maybe_throw(); exit_status = true; } catch (...) { did_throw = true; } print_exit_status("Manual handling", exit_status, did_throw); // Using scope_exit: runs on scope exit (success or exception) exit_status = did_throw = false; try { auto guard = std::experimental::scope_exit{[&]{ exit_status = true; } }; maybe_throw(); } catch (...) { did_throw = true; } print_exit_status("scope_exit", exit_status, did_throw); // Using scope_fail: runs only if an exception occurs exit_status = did_throw = false; try { auto guard = std::experimental::scope_fail{[&]{ exit_status = true; } }; maybe_throw(); } catch (...) { did_throw = true; } print_exit_status("scope_fail", exit_status, did_throw); // Using scope_success: runs only if no exception occurs exit_status = did_throw = false; try { auto guard = std::experimental::scope_success{[&]{ exit_status = true; } }; maybe_throw(); } catch (...) { did_throw = true; } print_exit_status("scope_success", exit_status, did_throw); }
輸出
Manual handling: Throwed exception yes Exit status pending scope_exit: Throwed exception no Exit status finished scope_fail: Throwed exception yes Exit status finished scope_success: Throwed exception yes Exit status pending
[edit] 參見
| 封裝一個函式物件,並在退出作用域時呼叫它 (類別模板) | |
| 封裝一個函數物件,並在正常離開作用域時呼叫它 (類別模板) | |
| (C++11) |
unique_ptr 的預設刪除器 (類別範本) |