Skip to content

Instantly share code, notes, and snippets.

@dgellow
Last active February 9, 2020 06:15
Show Gist options
  • Save dgellow/30cf3bc1ab895598c0159057fb351999 to your computer and use it in GitHub Desktop.
Save dgellow/30cf3bc1ab895598c0159057fb351999 to your computer and use it in GitHub Desktop.
C++ equivalent to Go's defer keyword. Extracted from GSL, see final_action and finally at https://github.com/microsoft/GSL/blob/master/include/gsl/gsl_util
#include <iostream>
#include <utility>
// Deferred allows you to ensure something gets run at the end of a scope
template <class F>
class Deferred {
public:
explicit Deferred(F f) noexcept : fn(std::move(f)) {}
Deferred(Deferred&& other) noexcept : fn(std::move(other.fn)), called(std::exchange(other.called, false)) {}
Deferred(const Deferred&) = delete;
Deferred& operator=(const Deferred&) = delete;
Deferred& operator=(Deferred&&) = delete;
~Deferred() noexcept {
if (called) fn();
}
private:
F fn;
bool called{true};
};
// defer() - convenience function to generate a Deferred
template <class F>
Deferred<F> defer(const F& f) noexcept {
return Deferred<F>(f);
}
template <class F>
Deferred<F> defer(F&& f) noexcept {
return Deferred<F>(std::forward<F>(f));
}
int main() {
auto _ = defer ([](){
std::cout << "Hi, I have been deferred :)" << std::endl;
});
std::cout << "Hello World!" << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment