How to get rid of the manual class template parameter specification

Is there a more general way to write a Finalizer class than this?

 #include <functional> #include <iostream> template <typename T> class Finalizer { public: Finalizer(const std::function<T>& f) : _f(f) {} ~Finalizer() { _f(); } private: std::function<T> _f; }; int main() { Finalizer<void()> finalizer([]() { std::cout << "str" << std::endl; }); } 

I want to get rid of the manual class template parameter specification in order to write code like this:

 Finalizer finalizer([]() { std::cout << "str" << std::endl; }); 

Is it possible?

+5
source share
1 answer

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; }); 
+5
source

Source: https://habr.com/ru/post/1244804/


All Articles