std::experimental::scope_exit
出自cppreference.com
< cpp | experimental
在標頭 <experimental/scope> 定義
|
||
template< class EF > class scope_exit; |
(庫基礎 TS v3) | |
類模板 scope_exit
是通用的作用域防護,有意使它在退出作用域時調用其退出函數。
scope_exit
非可複製構造 (CopyConstructible) 、可複製賦值 (CopyAssignable) 或可移動賦值 (MoveAssignable) ,然而若 EF
滿足某些要求則它可能為可移動構造 (MoveConstructible) ,這允許包裝 scope_exit
到另一對象中。
scope_exit
可為活躍,即在析構時調用其退出函數,或為不活躍,即在析構時不做任何事。在從退出函數構造後 scope_exit
為活躍。
scope_exit
能因手動或自動(由移動構造函數)在它上調用 release() 後變得不活躍。亦可由從另一不活躍的 scope_exit
初始化獲得不活躍的 scope_exit
。一旦 scope_exit
不活躍,則它不能再次變得活躍。
一個 scope_exit
等效地保有一個 EF
與一個指示它是否活躍的 bool 標籤。
目錄 |
[編輯] 模板形參
EF | - | 退出函數的類型 |
類型要求 | ||
-EF 可為:
| ||
-以無實參調用 std::remove_reference_t<EF> 的左值必須為良構。 |
[編輯] 成員函數
構造新的 scope_exit (公開成員函數) | |
在退出作用域時調用退出函數,若 scope_exit 為活躍,然後銷毀 scope_exit (公開成員函數) | |
operator= [棄置] |
scope_exit 不可賦值 (公開成員函數) |
修改器 | |
使 scope_exit 不活躍 (公開成員函數) |
[編輯] 推導指引
[編輯] 註解
構造擁有動態存儲期的 scope_exit
可能導致非預期的行為。
若存儲於 scope_exit
對象的 EF
引用到定義它的函數的局部變量,例如為按引用捕獲該變量的 lambda,則在該 scope_exit
的析構函數執行並調用退出函數時該變量可能已經被返回。這能導致令人詫異的行為。
[編輯] 示例
運行此代碼
#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 << " 抛出异常 " << (did_throw ? "是" : "否") << "\n"; std::cout << " 退出状态 " << (exit_status ? "完成" : "待定") << "\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}; // 在“作用域末尾”人工处理 try { maybe_throw(); exit_status = true; } catch (...) { did_throw = true; } print_exit_status("人工处理", exit_status, did_throw); // 使用 scope_exit:在(成功或异常)退出作用域时执行 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); // 使用 scope_fail:仅于发生异常时执行 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); // 使用 scope_success:仅于未发生异常时执行 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); }
輸出:
人工处理: 抛出异常 是 退出状态 待定 scope_exit: 抛出异常 否 退出状态 完成 scope_fail: 抛出异常 是 退出状态 完成 scope_success: 抛出异常 是 退出状态 待定
[編輯] 參閱
包裝函數對象並在通過異常退出作用域時調用 (類模板) | |
包裝函數對象並在正常退出作用域時調用 (類模板) | |
(C++11) |
unique_ptr 的默認刪除器 (類模板) |