Suppose we have a function f
which returns a value of some unknown type (let\'s call it T
) and takes a value of the type T
as an argum
Building on @Piotr S.'s excellent answer, for arbitrary functor types, if you know that there's exactly one operator()
overload with the right "pattern", so to speak, then you can do something like this:
// leave undefined
template
T return_type_helper(T (C::*)(T));
template
T return_type_helper(T (C::*)(T) const);
// 10 additional combinations of ref- and cv- qualifiers omitted, because I'm lazy
template
using functor_return_type = decltype(return_type_helper(&T::operator()));
This activates overload resolution and template argument deduction to determine the right operator()
.
And then you can combine those two:
template
struct voider { using type = void; };
template
using void_t = typename voider::type;
template
struct combined_return_type;
template
struct combined_return_type::type>> {
using type = typename return_type::type;
};
template
struct combined_return_type>> {
using type = functor_return_type;
};
template
using return_type_t = typename combined_return_type::type;
Demo.