这是将问题以至少可以重用的形式转移到专用包装器的尝试。
不确定正确性,甚至没有尝试编译一次。至少,在static_cast
按值返回时会进行不必要的复制。
我只是出于好奇而这样做,实际上并不需要解决这个问题,但它看起来相当繁重。
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 ) );
}