std::experimental::scope_fail

来自cppreference.com
在标头 <experimental/scope> 定义
template< class EF >
class scope_fail;
(库基础 TS v3)

类模板 scope_fail 是通用的作用域防护,有意使它在经由异常退出作用域时调用其退出函数。

scope_fail可复制构造 (CopyConstructible) 可复制赋值 (CopyAssignable) 可移动赋值 (MoveAssignable) ,然而若 EF 满足某些要求则它可能为可移动构造 (MoveConstructible) ,这允许包装 scope_fail 到另一对象中。

scope_fail 可为活跃,即在析构时调用其退出函数,或为不活跃,即在析构时不做任何事。在从退出函数构造后 scope_fail 为活跃。

scope_fail 能因手动或自动(由移动构造函数)在它上调用 release() 后变得不活跃。亦可由从另一不活跃的 scope_fail 初始化获得不活跃的 scope_fail。一旦 scope_fail 不活跃,则它不能再次变得活跃。

一个 scope_fail 等效地保有一个 EF 与一个指示它是否活跃的 bool 标签,还有一个用于检测是否在栈回溯期间调用析构函数的未捕捉异常的计数器。

目录

[编辑] 模板形参

EF - 退出函数的类型
类型要求
-
EF 可为:
-
以无��参调用 std::remove_reference_t<EF> 的左值必须为良构。

[编辑] 成员函数

构造新的 scope_fail
(公开成员函数) [编辑]
在经由异常退出作用域时调用退出函数,若 scope_fail 为活跃,然后销毁 scope_fail
(公开成员函数) [编辑]
operator=
[弃置]
scope_fail 不可赋值
(公开成员函数)
修改器
使 scope_fail 不活跃
(公开成员函数) [编辑]

[编辑] 推导指引

[编辑] 注解

构造拥有动态存储期的 scope_fail 可能导致非预期的行为。

从创建于另一线程的 scope_fail 构造 scope_fail 亦可能导致非预期的行为,因为可能在析构期间比较从另一线程获得的未捕捉异常计数。

[编辑] 示例

#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 的默认删除器
(类模板) [编辑]