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);
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 typedeftypenames the typedecltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...));otherwise, there shall be no membertype.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With