Return type - Part 1
Templates in C++ allows us to write generic concurrent programs. It is not unusual to have a template argument which represent a function. For example
template <typename Fun>
void function(Fun f, ...)the function’s argument is a function
f of type Fun.
If we use functions as template arguments, then we don’t know what is the return
type of the function. (For example, we don’t know the return type of
f.) There are some cases, when we would need to know the
return type of a function. For example, making a future with
std::async requires such knowledge.
Fortunately there exist a solution for this problem. The solution is
std::result_of. This class can figure out what is the return
type of the function at the compile time.
std::result_of
Let’s look at an example
template <typename Fun, typename... Args>
void checkType(Fun f, Args... args)
{
using return_t = typename std::result_of< Fun(Args...) >::type;
std::cout << "int: " << std::is_same<int, return_t>::value << "\n";
std::cout << "double: " << std::is_same<double, return_t>::value << "\n";
std::cout << "float: " << std::is_same<float, return_t>::value << "\n";
std::cout << std::endl;
}The checkType accepts two arguments. First one is a function
f of type Fun and the second one
represents variadic number of arguments. The assumption is that
args are the arguments of f. If you are
not familiar with functions, which have variadic number of arguments, look at
Variadic number of arguments.
The next line
using return_t = typename std::result_of< Fun(Args...) >::type;determines the return type of f. This is done with
std::result_of. The template parameter of
std::result_of must be a signature of a function. Then, the
std::result_of< >::type represents the return type of the
function, which is determined by the signature. The deduced
return type is stored in return_t.
In the next lines, the program prints information about
return_t. The statement
std::is_same<T, U>::valueis equal to true if T and
U are the same type. Otherwise, the statement is
false.
Using std::is_same< >, the program checks if the
return_t is equal to int or
double or float.
Examples
Let’s look at the behavior of the function checkType.
int fun1(int i)
{
return i;
}
double fun2(double d)
{
return d;
}
float fun3(int i1, int i2)
{
return static_cast<float>(i1 + i2);
}
int main()
{
int i = 1;
double d = 1.0;
std::cout << "Function1: " << std::endl;
checkType(fun1, i);
std::cout << "Function2: " << std::endl;
checkType(fun2, d);
std::cout << "Function3: " << std::endl;
checkType(fun3, i, i);
}We have three functions fun1, fun2 and
fun3, which return int,
double and float, respectively. In
main function, checkType prints
information about the return types of fun1,
fun2 and fun3 using
std::result_of< >.
The output of the program is:
Function1:
int: 1
double: 0
float: 0
Function2:
int: 0
double: 1
float: 0
Function3:
int: 0
double: 0
float: 1Summary
We learned how to deduce the return type of a function with
std::result_of<>.
Links: