【问题标题】:Determining return type of std::function确定 std::function 的返回类型
【发布时间】:2015-06-10 22:35:38
【问题描述】:

我正在编写一个模板函数,它接收一个std::function 对象(通过使用适当的参数调用std::bind 生成)。 在这个函数中,我想确定这个函数对象的返回类型。有可能吗?

事实上,我希望模板函数返回相同的类型。你能想出一种优雅的、基于标准的方法来实现这个目标吗?

类似:

template <typename T>
T::return_type functionObjWrapper(T functionObject) {
   // ...
   return functionObject();
}

谢谢

【问题讨论】:

  • std::bind 不返回 std::function
  • 不,但它确实返回一个可调用对象,这足以初始化 std::function

标签: c++ templates c++11


【解决方案1】:

您可以使用decltype 和尾随返回类型来做到这一点:

template <typename T>
auto functionObjWrapper(T functionObject) -> decltype(functionObject()) {
   // ...
   return functionObject();
}

【讨论】:

  • 仅兼容 C++14!
  • @DavidHaim 在 GCC 4.7.2(没有 C++14 模式)中使用 C++11 模式构建时工作正常。此外,尾随返回类型是 C++11 标准的一部分,decltype 也是如此。
  • @DavidHaim 这是普通的旧 C++11。在 C++14 中,您可以完全删除尾随返回类型
  • 此实现不可靠,因为调用 functionObject() 只是为了获取返回类型可能会修改可能不需要的静态变量。
  • @MosheRabaev decltype 是一个编译时构造,其工作方式类似于sizeof。它不计算给定的表达式,在decltype(functionObject()) 中实际上没有调用任何函数。
【解决方案2】:

您正在寻找std::function&lt;F&gt;::result_type

template <typename F>
typename std::function<F>::result_type
functionObjWrapper(std::function<F> functionObject) {
   // ...
   return functionObject();
}

std::function&lt;F&gt;::result_type 之前的 typename 是必需的,因为这是一个依赖类型名称。

【讨论】:

    【解决方案3】:
    template <class F>
    std::result_of_t<F&()> functionObjWrapper(F functionObject) {
      // ...
      return functionObject();
    }
    

    std::result_of 采用“看起来像函数调用”的类型表达式。然后它会告诉您如果使用该可调用类型和这些参数进行函数调用会发生什么。

    如果您缺少 C++14,请将 std::result_of_t&lt;?&gt; 替换为 typename std::result_of&lt;?&gt;::type,或者自己编写:

    template<class Sig>
    using result_of_t=typename std::result_of<Sig>::type;
    

    在许多 C++11 实现中,result_of 甚至对 SFINAE 友好。

    我使用F&amp;() 而不是F(),因为我们将使用F 类型的非常量左值来进行调用。如果您的最后一行是std::move(functionObject)()std::forward&lt;F&gt;(functionObject)(),您将使用result_of_t&lt;F()&gt;

    【讨论】:

      猜你喜欢
      • 2021-01-05
      • 2020-11-26
      • 2015-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多