Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way of using invoke_result?

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);
like image 568
Vincent Avatar asked Dec 18 '17 19:12

Vincent


1 Answers

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).

like image 122
Barry Avatar answered Sep 29 '22 14:09

Barry