Here is an attempt to move the task to the selected shell in such a way that it can at least be reused.
Not sure of the correctness, did not even try to compile it once. At the very least, static_cast
makes an unnecessary copy when returning by value.
I just do it out of curiosity, I really do not need to solve this problem, but it looks quite burdensome.
template< typename ftor, typename ... args > typename std::enable_if< ! std::is_void< typename std::result_of< ftor( args ... ) >::type >::value, typename std::result_of< ftor( args ... ) >::type >::type call_or_wrap_void( ftor && f, args && ... a ) { return std::forward< ftor >( f ) ( std::forward< args >( a ) ... ); } struct void_wrapper {}; template< typename ftor, typename ... args > typename std::enable_if< std::is_void< typename std::result_of< ftor( args ... ) >::type >::value, void_wrapper >::type call_or_wrap_void( ftor && f, args && ... a ) { std::forward< ftor >( f ) ( std::forward< args >( a ) ... ); return {}; } template< typename ftor, typename ... args > typename std::result_of< ftor( args ... ) >::type call_and_report( ftor && f, args && ... a ) { auto && ret{ call_or_wrap_void( std::forward< ftor >( f ), std::forward< args >( a ) ... ) }; std::cout << "Done!\n"; return static_cast< typename std::result_of< ftor( args ... ) >::type > ( std::move( ret ) ); }
source share