Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between std::result_of and decltype

I have some trouble understanding the need for std::result_of in C++0x. If I understood correctly, result_of is used to obtain the resulting type of invoking a function object with certain types of parameters. For example:

template <typename F, typename Arg> typename std::result_of<F(Arg)>::type invoke(F f, Arg a) {     return f(a); } 

I don't really see the difference with the following code:

template <typename F, typename Arg> auto invoke(F f, Arg a) -> decltype(f(a)) //uses the f parameter {     return f(a); } 

or

template <typename F, typename Arg> auto invoke(F f, Arg a) -> decltype(F()(a)); //"constructs" an F {     return f(a); } 

The only problem I can see with these two solutions is that we need to either:

  • have an instance of the functor to use it in the expression passed to decltype.
  • know a defined constructor for the functor.

Am I right in thinking that the only difference between decltype and result_of is that the first one needs an expression whereas the second does not?

like image 662
Luc Touraille Avatar asked Apr 22 '10 09:04

Luc Touraille


People also ask

What is Declval?

std::declval This is a helper function used to refer to members of a class in unevaluated operands, especially when either the constructor signature is unknown or when no objects of that type can be constructed (such as for abstract base classes).


1 Answers

result_of was introduced in Boost, and then included in TR1, and finally in C++0x. Therefore result_of has an advantage that is backward-compatible (with a suitable library).

decltype is an entirely new thing in C++0x, does not restrict only to return type of a function, and is a language feature.


Anyway, on gcc 4.5, result_of is implemented in terms of decltype:

  template<typename _Signature>     class result_of;    template<typename _Functor, typename... _ArgTypes>     struct result_of<_Functor(_ArgTypes...)>     {       typedef         decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) )         type;     }; 
like image 103
kennytm Avatar answered Sep 26 '22 03:09

kennytm