11

On cppreference, it is written that the correct way of using std::result_of is:

template<class F, class... Args>
std::result_of_t<F&&(Args&&...)> 
// instead of std::result_of_t<F(Args...)>, which is wrong
  my_invoke(F&& f, Args&&... args) { 
    /* implementation */
}

I was wondering how std::invoke_result_t should be used: invoke_result_t:

template<class F, class... Args> 
std::invoke_result_t<F&&, Args&&...> my_invoke(F&& f, Args&&... args);

Or:

template<class F, class... Args> 
std::invoke_result_t<F, Args...> my_invoke(F&& f, Args&&... args);
Vincent
  • 57,703
  • 61
  • 205
  • 388

1 Answers1

11

invoke_result is defined in terms of declval:

If the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is well-formed when treated as an unevaluated operand, the member typedef type names the type decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...)); otherwise, there shall be no member type.

and declval is specified as:

template<class T> add_rvalue_reference_t<T> declval() noexcept;

So there's no difference between std::invoke_result_t<F&&, Args&&...> and std::invoke_result_t<F, Args...>. Well, the latter is 4 characters shorter, but they mean exactly the same thing (since neither F nor Args... could be void).

AndyG
  • 39,700
  • 8
  • 109
  • 143
Barry
  • 286,269
  • 29
  • 621
  • 977
  • 1
    There might be oddball cases where you get the template arguments from somewhere else and one isn't referenceable, in which case the `&&` version may cause an error while the plain version doesn't. But it's pretty far-fetched. – T.C. Dec 18 '17 at 20:53
  • Caveat is, if your return type is void, the invoke_result_t is void and ::type doesn't exist... – cerkiewny Feb 24 '20 at 15:16
  • @cerkiewny Which `::type` doesn't exist? `invoke_result_t` works fine for `void` return types. – Barry Feb 24 '20 at 15:24
  • 1
    well I have the problem in which apparently the ::type doesn't exsit for invoke_result ::type, I need to investigate further though as behaviour clearly varies between gcc and clang, it might be a problem somewhere else in my system, trying to create minimal example with the difference – cerkiewny Feb 24 '20 at 22:52