命名空間
變體
動作

std::experimental::scope_fail

出自 cppreference.com
定義於標頭檔 <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] 參見

封裝一個函式物件,並在退出作用域時呼叫它
(類別模板) [編輯]
封裝一個函數物件,並在正常離開作用域時呼叫它
(類別模板) [編輯]
unique_ptr 的預設刪除器
(類別範本) [編輯]
English Deutsch 日本語 中文(简体) 中文(繁體)