Given that your operation does not depend on the result of the function, you can do it without a specialization. It is ok for a function returning void
to return an expression of type void
. So the return
part is not the troublesome one, but you need to figure out a way to do the pre and post operations. Constructors and destructors will help you there:
struct do_something_helper{ do_something_helper() { // do something first (e.g. take a lock) } ~do_something_helper() { // do something after (e.g. release a lock) }};
Then you can write your function like this:
template<typename T>T Foo( T(*Func)() ) { do_something_helper _dummy_helper; // constructor called here return Func(); // destructor called here}
For a more general solution using lambdas as you commented, it could look like this:
template< typename Pre, typename Post >struct scope_guard{ scope_guard( Pre&& pre, Post&& post ) : _post( std::forward< Post >( post ) ) { pre(); } ~scope_guard() { _post(); } Post _post;};template< typename Pre, typename Post >scope_guard< Pre, Post > make_scope_guard( Pre&& pre, Post&& post ){ return scope_guard< Pre, Post >( std::forward< Pre >( pre ), std::forward< Post >( post ) );}template<typename T>T Foo( T(*Func)() ) { auto do_something_helper = make_scope_guard( [](){ /* do something first (e.g. take a lock) */ }, [](){ /* do something after (e.g. release a lock) */ } ); return Func();}
A type-erased version using std::function< void() >
would be easier to write and use, but it would be rather inefficient.