Reputation: 206737
I have read the following related questions:
and the page on std::result_of
at cppreference.com.
All of them seem to indicate that I should be able to use:
std::result_of<int(int)>::type v1 = 10;
However, when I tried building the following program using g++ 4.9.2
#include <type_traits>
int foo()
{
return 0;
}
int main()
{
std::result_of<int(int)>::type v1 = 10; // LINE A
std::result_of<decltype(foo)>::type v2 = 20; // LINE B
return 0;
}
I get error messages for "LINE A" and "LINE B". The error messages are:
socc.cc: In function ‘int main()’:
socc.cc:10:5: error: ‘type’ is not a member of ‘std::result_of<int(int)>’
std::result_of<int(int)>::type v1 = 10;
^
socc.cc:11:5: error: ‘type’ is not a member of ‘std::result_of<int()>’
std::result_of<decltype(foo)>::type v2 = 20;
^
The command I used to compile:
g++ -std=c++11 -Wall socc.cc -o socc
FWIW, using
typename std::result_of<int(int)>::type v1 = 10;
typename std::result_of<decltype(foo)>::type v2 = 20;
didn't make a difference.
It seems that I am failing to understand how result_of
is supposed to be used.
Can you explain why I am getting the compiler errors?
Upvotes: 12
Views: 2019
Reputation: 96855
To use result_of
, the type supplied must be a function type where the return type is the type of a Callable and the parameter list contains the types of the arguments to call it with. result_of<int(int)>
therefore asks "what type will I get when I call declval<int>()
with the argument declval<int>()
". The answer is that there is no type, because int
is not a function type.
Here's an excerpt from Table 57:
If the expression
INVOKE(declval<Fn>(), declval<ArgTypes>()...)
is well formed when treated as an unevaluated operand (Clause 5), the member typedef type shall name the typedecltype(INVOKE (declval<Fn>(), declval<ArgTypes>()...));
otherwise, there shall be no membertype
Given the function foo
, you can use:
std::result_of_t<decltype((foo))()> v1 = 10;
std::result_of_t<decltype(&foo)()> v2 = 10;
Upvotes: 3
Reputation: 8537
As stated in the link you have already posted, the first part of the argument to result_of
must be a callable type or a reference to a function.
Suppose you have a
struct Callable
{
int operator()(double);
void operator()(int);
};
then result_of
helps you determining the return type, if you know the type of the arguments. For the example above:
result_of<Callable(int)>::type == void ... per definition
result_of<Callable(double)>::type == int ... per definition
result_of<Callable(char)>::type == void ... the int-overload matches better
result_of<Callable(float)>::type == int ... the double-overload matches better
In order to find the return type of the function foo
you would have to go via a function reference:
result_of<decltype(foo)& ()>::type == int
But this seems a bit twisted as you could directly write
decltype(foo()) == int
Upvotes: 11
Reputation: 15586
You seem to assume std::result_of<R(Args...)>::type
to be simply R
- that is, the result type of a function having signature R(Args...)
. But std::result_of<F(Args...)>::type
is the result of calling an instance of type F
with arguments of types Args...
.
So, std::result_of<int(int)>::type
does not make sense - int
objects are not callable.
Please, read cppreference again :)
Upvotes: 12