Seems C++14 auto
keyword can be used to appear at the location of function definition as to indicate the return type. In this case, is std::result_of
still needed? Isn't it obsolete now?
Yes, absolutely.
Sometimes you want the return type, but not as the result of the function. Let's say I have a vector<X>
and I want to apply a function to each element and return the result. This operation is called map
or fmap
, and we might implement the signature thusly:
template <class T, class F,
class U = std::decay_t<std::result_of_t<F&(T const&)>>>
std::vector<U> map(std::vector<T> const&, F );
You could make the return type auto
, but regardless, you need to compute that type U
and auto
won't give it to you. Any time you want the result of a function call that won't necessarily be the return type, auto
won't cut it.
SFINAE. Consider the difference between:
template <class F>
decltype(auto) foo(F f) { return f(0); }
template <class F>
std::result_of_t<F&(int)> bar(F f) { return f(0); }
If F
is not invokable with an int
, then instantiating foo()
is a hard compile error but bar()
would simply be removed from the overload set. This can be very valuable in generic code, as you can test expressions for well-formedness.
Annotation. auto
tells you nothing about the function return type. If the function is returning the result of invoking one callable with some args, std::result_of_t<F(A, B)>
in of itself tells me what that function is doing. auto
tells me nothing.
Really a better question may be... why do we need std::result_of
if we have decltype
. Those seem more closely related. After all, I can do decltype(x+1)
, how would I express that in terms of result_of
?! decltype
is clearly better. Well, it turns out there are some slight differences between the two even when it comes to determining the result of a function invocation.