This seems to be solved for the case of lambdas in this question. But that one is a 2011 answer and I\'m looking for a general case: lambdas, regular functions, and functors
Assuming that:
decltype()
nor std::result_of<>
is an option.operator()
.then you can use the below trait that infers the return type of any functor object:
template
struct return_type_impl;
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type_impl { using type = R; };
template
struct return_type
: return_type_impl {};
template
struct return_type
: return_type_impl {};
template
using return_type_t = typename return_type::type;
Tests:
#include
template
void test(F h)
{
static_assert(std::is_same, int>{}, "!");
return_type_t i = 1;
}
int function(int i) { return 2*i; }
int c_varargs_function(...) { return 1; }
struct A
{
int mem_function(double, float) { return 1; }
};
int main()
{
// Function
test(function);
// C-style variadic function
test(c_varargs_function);
// Non-generic lambda
test([](int i) { return 2*i; });
// Member function
test(&A::mem_function);
}
DEMO