In C ++, type inference is only available for function templates, not class templates. To perform the subtraction of the template argument, you need make_finalizer
.
Also, you do not need to use std::function
at all, you do not need to pay for the execution time if you really do not want to be erased.
template <typename F> class Finalizer { public: Finalizer(const F & c) : f_(c) {} Finalizer(F && c) : f_(std::move(c)) {} Finalizer(const Finalizer &) = delete; Finalizer(Finalizer && other) : valid_(other.valid), f_(std::move(other.f_)) { other.valid_ = false; } Finalizer& operator=(const Finalizer &) = delete; Finalizer& operator=(Finalizer && other) { Finalizer tmp(std::move(other)); swap(tmp); return *this; } ~Finalizer() { if ( valid_ ) f_(); } void swap(Finalizer & other) noexcept { using std::swap; swap(other.valid_, valid_); swap(other.f_, f_); } private: bool valid_ = true; F f_; }; template<class F> Finalizer< std::remove_reference_t<F> > at_scope_exit(F && x) { return Finalizer< std::remove_reference_t<F> >(std::forward<F>(x)); }
And use it with auto:
auto x = at_scope_exit([]() { std::cout << "Hello world" << std::endl; });
source share