I am learning how to get type
of the return value of overloaded function test()
vs test(double)
.
I modified code from a SO answer (by chris).
#include <type_traits>
#include <utility>
int test();
double test(double x);
template<typename... Ts>
using TestType = decltype(test(std::declval<Ts>()...))(Ts...);
int main() {
std::result_of< TestType<double> >::type n = 0;
//^ ### compile error ###
using doubleDat = std::result_of< TestType<double> >::type ;
doubleDat n=0;
}
I got a compile error.
error: no type named 'type' in 'std::result_of'
As I understand:-
TestType<...>
is "variadic template".
In my own words, it acts like a packed abbreviation that have any amount of parameters.
The TestType<double>
is id of the test(double)
function.
std::result_of<TestType<double>>::type
is the return type of test(double)
.doubleDat
should be double
.Question: Why it doesn't compile? How to solve it?
I have read these :-
std::result_of
std::result_of
Clue: After a long search, I get faint smell that my code suffers "Most vexing parse".
Look at what your TestType<double>
expands to:
test(std::declval<double>())(double)
test(std::decvlal<double>)
is double
so you get double(double)
result_of<double(double)>::type
asks if you can invoke a double
with an argument of type double
.
The answer is no, because double
is not callable, so there's no nested type.
You need to read the documentation for result_of
to understand how to use it. The type result_of<F(Arg)>::type
is the result of invoking an F
with an argument Arg
. If F
is callable with an argument Arg
you get the return type, if it is not callable with an argument Arg
then the nested type
doesn't exist.
So this would work:
using func_type = TestType<double>;
using doubleDat = std::result_of<func_type*(double)>::type;
This creates an alias for a function of type TestType<double>
(i.e. double(double)
) and then asks if you can invoke a pointer to that type (i.e. double(*)(double)
) with an argument of type double
. And you can, so you the type
is valid.