std::experimental::scope_exit

出自cppreference.com
在標頭 <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:
  抛出异常  是
  退出状态  待定

[編輯] 參閱

包裝函數對象並在通過異常退出作用域時調用
(類模板) [編輯]
包裝函數對象並在正常退出作用域時調用
(類模板) [編輯]
unique_ptr 的默認刪除器
(類模板) [編輯]