Search code examples
c++templatesc++14

Get function return type in template


How can I get return type for any function passed to template?
I don't know how to convert between template<typename T> and template<typename Result, typename Args...>:

template<typename T>
void print_name(T f)
{
    static_assert(internal::is_function_pointer<T>::value
            || std::is_member_function_pointer<T>::value,
            "T must be function or member function pointer.");
    typename decltype(f(...)) Result; // ???
    typename std::result_of<T>()::type Result; // ???
    printf("%s\n", typeid(Result).name());
}

void f_void() {}
int f_int(int x) { return 0; }
float f_float(int x, int y) { return 0.f; }
struct X { int f(int x, float y) { return 0; } };

int main()
{
    print_name(f_void);
    print_name(f_int);
    print_name(f_float);
    print_name(&X::f);
    return 0;
}

How can i get type Result inside function print_name?


Solution

  • A possible solution is using a function declaration that extracts the return type as well as all the parameters. You don't have even to define it.
    It follows a minimal, working example:

    #include<typeinfo>
    #include<cstdio>
    
    template<typename R, typename... A>
    R ret(R(*)(A...));
    
    template<typename C, typename R, typename... A>
    R ret(R(C::*)(A...));
    
    template<typename T>
    void print_name(T f)
    {
        printf("%s\n", typeid(decltype(ret(f))).name());
    }
    
    void f_void() {}
    int f_int(int x) { return 0; }
    float f_float(int x, int y) { return 0.f; }
    struct X { int f(int x, float y) { return 0; } };
    
    int main()
    {
        print_name(f_void);
        print_name(f_int);
        print_name(f_float);
        print_name(&X::f);
        return 0;
    }
    

    As you can see, the declarations provided for ret has the same return type of the submitted function or member function.
    A decltype does the rest.