Return 只使用类型信息而不是对象信息的调用类型

Return type of a call only using information on types and not on objects

考虑以下代码:

template <class F, class... Args>
void function(F&& f, Args&&... args)
{
    using type1 = decltype(std::forward<F>(f)(std::forwards<Args>(args)...));
    using type2 = decltype(/*equivalent expression but only using types */);
}

有没有办法让 type2 在所有情况下都与 type1 相同,但只使用 decltype 表达式中的类型,或者换句话说,只使用 FArgs 而不是 fargs?

也许您想要使用 declval 的解决方案是:

template <class F, class... Args>
void function(F&& f, Args&&... args)
{
    using type1 = decltype(std::forward<F>(f)(std::forward<Args>(args)...));
    using type2 = decltype(std::forward<F>(declval<F>())(std::forward<Args>(declval<Args>())...));
}

希望对您有所帮助

您可以仅使用 C++11 并且不使用 decltype 使用 std::result_of:

来完成此操作
using type2 = typename std::result_of<F&&(Args&&...)>::type;

Example in compiler explorer.

一旦您开始使用 C++17,您应该按照 documentation.

中的描述将 std::result_of 替换为 std::invoke_result

从这里开始:

decltype(std::forward<F>(f)(std::forwards<Args>(args)...));

改为:

decltype(std::declval<F>()(std::declval<Args>()...));

完成了。 std::declval<T>() 是一个没有实现的函数,它具有与 std::forward.

相同的 return 类型

has std::result_of (and std::result_of_t),但它有一些不完美的小问题。您可以通过使用 &&:

来解决这些问题
std::result_of_t< F&&( Args&&... ) >

中,他们添加了 invoke_result 来解决这些问题:

std::invoke_result_t< F, Args... >

怪癖是因为函数调用签名中允许的类型并非所有类型,并且语言以某些方式默默地调整它们(删除顶级常量,不允许某些类型是 returned 等)。