#include <type_traits>
#include <iostream>
using namespace std;
template<typename T, typename ...U>
auto time_function(T&& func, U&& ...args)
-> typename enable_if<is_same<decltype(func(args...)), void>::value>::type
{
std::cout<<"timing void function"<<std::endl;
std::forward<T>(func)(std::forward<U>(args)...);
std::cout<<"timing over"<<std::endl;
}
template<typename T, typename ...U>
auto time_function(T&& func, U&& ...args)
-> typename enable_if<!is_same<decltype(func(args...)), void>::value, decltype(func(args...))>::type
{
std::cout<<"timing returning function"<<std::endl;
auto val = std::forward<T>(func)(std::forward<U>(args)...);
std::cout<<"timing over"<<std::endl;
return val;
}
void foo(int){}
int foo_return(int){return 0;}
int main()
{
time_function(foo, 2);
int i = time_function(&foo_return, 1); //this generates an error
std::cout<<i<<std::endl;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8aW9zdHJlYW0+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSAuLi5VPgogYXV0byB0aW1lX2Z1bmN0aW9uKFQmJiBmdW5jLCBVJiYgLi4uYXJncykgCiAgICAtPiB0eXBlbmFtZSBlbmFibGVfaWY8aXNfc2FtZTxkZWNsdHlwZShmdW5jKGFyZ3MuLi4pKSwgdm9pZD46OnZhbHVlPjo6dHlwZQp7CiAgICBzdGQ6OmNvdXQ8PCJ0aW1pbmcgdm9pZCBmdW5jdGlvbiI8PHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Zm9yd2FyZDxUPihmdW5jKShzdGQ6OmZvcndhcmQ8VT4oYXJncykuLi4pOwoKICAgIHN0ZDo6Y291dDw8InRpbWluZyBvdmVyIjw8c3RkOjplbmRsOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSAuLi5VPgphdXRvIHRpbWVfZnVuY3Rpb24oVCYmIGZ1bmMsIFUmJiAuLi5hcmdzKQogLT4gdHlwZW5hbWUgZW5hYmxlX2lmPCFpc19zYW1lPGRlY2x0eXBlKGZ1bmMoYXJncy4uLikpLCB2b2lkPjo6dmFsdWUsIGRlY2x0eXBlKGZ1bmMoYXJncy4uLikpPjo6dHlwZQp7CiAgICBzdGQ6OmNvdXQ8PCJ0aW1pbmcgcmV0dXJuaW5nIGZ1bmN0aW9uIjw8c3RkOjplbmRsOwogICAgYXV0byB2YWwgPSBzdGQ6OmZvcndhcmQ8VD4oZnVuYykoc3RkOjpmb3J3YXJkPFU+KGFyZ3MpLi4uKTsKCiAgICBzdGQ6OmNvdXQ8PCJ0aW1pbmcgb3ZlciI8PHN0ZDo6ZW5kbDsKCiAgICByZXR1cm4gdmFsOwp9CgoKdm9pZCBmb28oaW50KXt9CmludCBmb29fcmV0dXJuKGludCl7cmV0dXJuIDA7fQoKaW50IG1haW4oKQp7CgogICAgdGltZV9mdW5jdGlvbihmb28sIDIpOwogICAgaW50IGkgPSB0aW1lX2Z1bmN0aW9uKCZmb29fcmV0dXJuLCAxKTsgLy90aGlzIGdlbmVyYXRlcyBhbiBlcnJvcgogICAgc3RkOjpjb3V0PDxpPDxzdGQ6OmVuZGw7Cgp9