FinallyScopeExit
对于我们不想编写特殊类来处理某些资源的情况,我们可以编写一个泛型类:
template<typename Function>
class Finally final
{
public:
explicit Finally(Function f) : f(std::move(f)) {}
~Finally() { f(); } // (1) See below
Finally(const Finally&) = delete;
Finally(Finally&&) = default;
Finally& operator =(const Finally&) = delete;
Finally& operator =(Finally&&) = delete;
private:
Function f;
};
// Execute the function f when the returned object goes out of scope.
template<typename Function>
auto onExit(Function &&f) { return Finally<std::decay_t<Function>>{std::forward<Function>(f)}; }
它的示例用法
void foo(std::vector<int>& v, int i)
{
// ...
v[i] += 42;
auto autoRollBackChange = onExit([&](){ v[i] -= 42; });
// ... code as recursive call `foo(v, i + 1)`
}
注意(1):必须考虑一些关于析构函数定义的讨论来处理异常:
~
Finally()noexcept { f(); }
:在例外的情况下调用std::terminate
~
Finally()noexcept(noexcept(
f())) { f(); }
:仅在堆栈展开期间发生异常时调用terminate()
。~
Finally()noexcept { try { f(); } catch (...) { /* ignore exception (might log it) */} }
没有std::terminate
调用,但是我们无法处理错误(即使是非堆栈展开)。