使用invoke_result的正确方法?

Vin*_*ent 6 c++ result-of forwarding-reference c++17

在cppreference上,写道正确的使用方法std::result_of是:

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 */
}
Run Code Online (Sandbox Code Playgroud)

我想知道std::invoke_result_t应该如何使用 invoke_result_t:

template<class F, class... Args> 
std::invoke_result_t<F&&, Args&&...> my_invoke(F&& f, Args&&... args);
Run Code Online (Sandbox Code Playgroud)

要么:

template<class F, class... Args> 
std::invoke_result_t<F, Args...> my_invoke(F&& f, Args&&... args);
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 5

invoke_result定义如下declval:

如果在将表达式INVOKE(declval<Fn>(), declval<ArgTypes>()...)视为未求值的操作数时该表达式格式正确,则成员typedef type将该类型命名,decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...));否则,将不存在member type。

并declval指定为:

template<class T> add_rvalue_reference_t<T> declval() noexcept;
Run Code Online (Sandbox Code Playgroud)

因此,std::invoke_result_t<F&&, Args&&...>和之间没有区别std::invoke_result_t<F, Args...>。好吧,后者要短4个字符,但它们表示的是完全相同的东西(因为既不是F也不Args...是void)。