#include #include #include class at_exit { public: template at_exit(C2 &&_c, A2 &&..._a) : function( std::bind_front(std::forward(_c), std::forward(_a)...)) {} at_exit(const at_exit &) = delete; at_exit(const at_exit &&) = delete; at_exit &operator=(const at_exit &) = delete; at_exit &operator=(const at_exit &&) = delete; ~at_exit() { function(); } private: std::function function; }; void msg(std::string_view s) { puts(s.data()); } struct S1 { void operator()(std::string_view s) const { puts(s.data()); } }; struct S2 { void print(std::string_view s) const { puts(s.data()); } }; at_exit global1([] { puts("[global1]: lambda"); }); at_exit global2(msg, "[global2]: function"); at_exit global3(S1{}, "[global3]: struct::operator()"); at_exit global4(&S2::print, S2{}, "[global4]: struct::method"); int main() { at_exit local1([] { puts("[local1]: lambda"); }); at_exit local2(msg, "[local2]: function"); at_exit local3(S1{}, "[local3]: struct::operator()"); at_exit local4(&S2::print, S2{}, "[local4]: struct::method"); }