Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 570
Tomashu Avatar asked Dec 23 '16 12:12

Tomashu


People also ask

Can you use auto as a return type in C++?

In C++14, you can just use auto as a return type.

What is a templated function?

Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.

Can templates be used for functions?

Templates Specialization is defined as a mechanism that allows any programmer to use types as parameters for a class or a function. A function/class defined using the template is called a generic function/class, and the ability to use and create generic functions/classes is one of the critical features of C++.

What is the syntax of function template?

A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.


2 Answers

as of C++ 20, the answer is

std::invoke_result_t<T>
like image 193
noseems Avatar answered Sep 27 '22 18:09

noseems


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.

like image 42
skypjack Avatar answered Sep 27 '22 19:09

skypjack