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>::value
is 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: 1
Summary
We learned how to deduce the return type of a function with
std::result_of<>
.
Links: