std::experimental::scope_exit
出自cppreference.com
< cpp | experimental
| 在標頭 <experimental/scope> 定義
|
||
| |
(庫基礎 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) |
std::unique_ptr 的默認刪除器 (類模板) |