还没有(已经提出了这方面的建议)。但是实现一个通用的就足够简单了。
struct scope_exit {
std::function<void()> f_;
explicit scope_exit(std::function<void()> f) noexcept : f_(std::move(f)) {}
~scope_exit() { if (f_) f_(); }
};
// ...
m_theVariableToChange = true;
scope_exit resetFalse([&m_theVariableToChange]() { m_theVariableToChange = false; });
为简单起见,我已经编辑了复制和移动构造函数等......
将它们标记为= delete
将使上述成为最小的解决方案。更远; 如果需要,可以允许移动,但应禁止复制。
更完整的scope_exit
样子(此处为在线演示);
template <typename F>
struct scope_exit {
F f_;
bool run_;
explicit scope_exit(F f) noexcept : f_(std::move(f)), run_(true) {}
scope_exit(scope_exit&& rhs) noexcept : f_((rhs.run_ = false, std::move(rhs.f_))), run_(true) {}
~scope_exit()
{
if (run_)
f_(); // RAII semantics apply, expected not to throw
}
// "in place" construction expected, no default ctor provided either
// also unclear what should be done with the old functor, should it
// be called since it is no longer needed, or not since *this is not
// going out of scope just yet...
scope_exit& operator=(scope_exit&& rhs) = delete;
// to be explicit...
scope_exit(scope_exit const&) = delete;
scope_exit& operator=(scope_exit const&) = delete;
};
template <typename F>
scope_exit<F> make_scope_exit(F&& f) noexcept
{
return scope_exit<F>{ std::forward<F>(f) };
}
实施说明;
std::function<void()>
可用于擦除函子的类型。std::function<void()>
根据所持有函数的特定异常,为移动构造函数提供异常保证。此实现的示例可在此处找到
- 这些异常规范与 C++ 提案和 GSL 实现一致
- 我已经修改了C++ 提案中的大部分动机
noexcept
,更重要的细节
- 析构函数的“通常” RAII 语义,因此“范围退出”函数适用;它不会
throw
,这也与 C++11 中关于析构函数的默认异常规范的规范一致。请参阅cppreference、SO Q&A、GotW#47和HIC++
可以找到其他实现;