【问题标题】:Get the result type of a function in c++11在c++11中获取函数的结果类型
【发布时间】:2013-01-03 18:05:03
【问题描述】:

考虑 C++11 中的以下函数:

template<class Function, class... Args, typename ReturnType = /*SOMETHING*/> 
inline ReturnType apply(Function&& f, const Args&... args);

我希望ReturnType 等于f(args...) 的结果类型 我要写什么而不是/*SOMETHING*/

【问题讨论】:

  • 不会decltype(f(args...)) 做吗?

标签: c++ templates c++11 typetraits


【解决方案1】:

我认为您应该使用 trailing-return-type 将函数模板重写为:

template<class Function, class... Args> 
inline auto apply(Function&& f, const Args&... args) -> decltype(f(args...))
{
    typedef decltype(f(args...)) ReturnType;

    //your code; you can use the above typedef.
}

请注意,如果您将args 传递为Args&amp;&amp;... 而不是const Args&amp;...,那么最好在f 中使用std::forward 作为:

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

当你使用const Args&amp;... 时,std::forward 没有多大意义(至少对我而言)。

最好将args 传递为Args&amp;&amp;... 称为universal-reference 并使用std::forward

【讨论】:

  • 将参数作为通用引用还是作为常量引用传递更好?
  • @Vincent:通用参考。这样更好。
【解决方案2】:

它不需要是模板参数,因为它不用于重载解析。试试

template<class Function, class... Args> 
inline auto apply(Function&& f, const Args&... args) -> decltype(f(std::forward<const Args &>(args)...));

【讨论】:

  • 有和没有 std::forward 的版本有什么区别?
  • 他正在通过Args 传递const &amp;。那么使用std::forward 有意义吗?
  • @Nawaz:也许不是,但我怀疑它实际上应该是Args&amp;&amp; ...args。然而,这是一个不同的问题。我只是希望这个答案在面对这样的变化时是稳健的。
  • @Vincent:不同之处在于,如果您决定将来使用完美转发,这不会中断。
  • 这还能用吗?我看到它std::forward&lt;Args&gt;(args) 的方式会将argsconst Args&amp; 转换为Args&amp;&amp;(请注意,我谈论的是易于表达的包中的单个元素),这意味着它将消除常量(如果它甚至可以工作,这是不应该的,因为forward&lt;T&gt; 应该采用T&amp;T&amp;&amp;,而不是const T&amp;)。
【解决方案3】:

在某些情况下 std::result_of 更有用。例如,假设你要传递这个函数:

int ff(int& out, int in);

在 apply() 内部这样调用它

int res;
f(res, args...);

那么我就不会知道如何使用 decltype,因为我手头没有 int 左值引用。使用 result_of,您不需要变量:

template<class Function, class... Args> 
typename std::result_of<Function(const Args&...)>::type apply(Function&& f, const Args&... args)
{
  typedef typename std::result_of<F(const Args&...)>::type ReturnType;

  // your code
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 2011-12-23
    • 2016-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多