Not yet (there have been proposals for this). But implementing a generic one is simple enough;
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; });
For simplicity above, I've redacted the copy and move constructors etc...
Marking them as = delete
will make the above a minimal solution. Further; moving could be allowed if desired, but copying should be prohibited.
A more complete scope_exit
would look like (online demo here);
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) };
}
Notes on the implementation;
std::function<void()>
can be used to erase the type of the functor. std::function<void()>
offers exception guarantees on the move constructors based on the exception specific of the held function. A sample of this implementation is found here
- These exception specifications are consistent the C++ proposal and GSL implementations
- I've redacted most of the motivation for the
noexcept
, more substantial detail is found in the C++ proposal
- The "usual" RAII semantics of the destructor, hence the "scope exit" function is applicable; it will not
throw
, this is also consistent with the C++11 specification on the default exception specification for a destructor. See cppreference, SO Q&A, GotW#47 and HIC++
Other implementations can be found;
var = false;
... – Lactometer