std::experimental:: scope_fail
|
定义于头文件
<experimental/scope>
|
||
|
template
<
class
EF
>
class scope_fail ; |
(库基础技术规范 v3) | |
类模板
scope_fail
是一种通用作用域守卫,旨在当作用域通过异常退出时调用其退出函数。
scope_fail
不具备
可复制构造
、
可复制赋值
或
可移动赋值
的特性,但在
EF
满足特定要求时可能具备
可移动构造
的特性,这允许将
scope_fail
包装到其他对象中。
一个
scope_fail
可以是激活状态(即在析构时调用其退出函数)或非激活状态(即在析构时不执行任何操作)。
scope_fail
在通过退出函数构造后处于激活状态。
一个
scope_fail
可以通过手动或自动(通过移动构造函数)调用其
release()
方法变为非活跃状态。通过使用另一个非活跃的
scope_fail
进行初始化也可以获得非活跃的
scope_fail
。一旦
scope_fail
变为非活跃状态,就无法再次变为活跃状态。
一个
scope_fail
实际上持有一个
EF
和一个
bool
标志位(指示其是否处于激活状态),以及一个用于检测析构函数是否在栈展开期间被调用的未捕获异常计数器。
目录 |
模板参数
| EF | - | 存储的退出函数类型 |
| 类型要求 | ||
-
EF
应为以下类型之一:
|
||
|
-
|
||
成员函数
构造新的
scope_fail
(公开成员函数) |
|
若
scope_fail
处于活动状态,在因异常退出作用域时调用退出函数,然后销毁该
scope_fail
(公开成员函数) |
|
|
operator=
[deleted]
|
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 << " Throwed exception " << (did_throw ? "yes" : "no") << "\n"; std::cout << " Exit status " << (exit_status ? "finished" : "pending") << "\n\n"; } // 随机抛出异常(50%概率) 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("Manual handling", 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); }
输出:
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
参见
|
包装函数对象并在退出作用域时调用它
(类模板) |
|
|
包装函数对象并在正常退出作用域时调用它
(类模板) |
|
|
(C++11)
|
unique_ptr
的默认删除器
(类模板) |