Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't std::result_of<int(int)>::type valid?

Tags:

c++

c++11

I have read the following related questions:

  1. std::result_of simple function
  2. decltype, result_of, or typeof?

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?

like image 406
R Sahu Avatar asked Jun 18 '15 15:06

R Sahu


1 Answers

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 type decltype(INVOKE (declval<Fn>(), declval<ArgTypes>()...)); otherwise, there shall be no member type

Given the function foo, you can use:

 std::result_of_t<decltype((foo))()> v1 = 10;
 std::result_of_t<decltype(&foo)()> v2 = 10;
like image 141
David G Avatar answered Oct 05 '22 05:10

David G