仅使用有关类型而非对象的信息返回调用类型

时间:2017-12-18 17:33:54

标签: c++ c++11 decltype perfect-forwarding forwarding-reference

请考虑以下代码:

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 */);
}

是否可以在所有情况下使type2type1相同,但仅使用decltype表达式中的类型,或者仅使用FArgs而非fargs

3 个答案:

答案 0 :(得分:6)

您可以仅使用C ++ 11而不使用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

答案 1 :(得分:3)

使用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>())...));
}

希望这有帮助

答案 2 :(得分:1)

从这开始:

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

改为:

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

并完成了。 std::declval<T>()是一个没有实现的函数,其返回类型与std::forward相同。

std::result_of(而std::result_of_t),但这有一些小问题使其不完美。您可以使用&&

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

中,他们添加invoke_result来修复这些怪癖:

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

怪癖是因为函数调用签名中允许的类型不是所有类型,并且语言以某种方式静默调整它们(删除顶级const,不允许返回某些类型等)。 / p>