【问题标题】:Determine the return-type of a function which is given as a templated-parameter确定作为模板参数给出的函数的返回类型
【发布时间】:2015-06-21 20:26:03
【问题描述】:

我有一个带有模板参数的函数,它接受另一个函数。在该函数中,我想调用一个不同的模板函数,该函数需要使用函数参数的返回类型进行实例化。

由于我可能把最后一段搞砸了,让我试着用一个例子来澄清一下:

template <typename funT>
void foo(funT function_to_call)
{
    auto data = bar<funT::return_value>();
    /// do some stuff with data.
    /// call function_to_call, but bar needed to be called first.
}

如何获得 funT::return_value ?

非常感谢,

【问题讨论】:

  • 问题一直是市场上一个不相关的复制品,不是吗?
  • 是的,据我所知,答案与我的问题无关,除了它们都与 C++ 模板有关。
  • 不管怎样,只要funT不带任何参数,你就可以使用std::result_of&lt;funT()&gt;::type访问返回类型。

标签: c++ templates


【解决方案1】:

您可以通过以下方式使用类型特征,特别是 std::result_of

template <typename funT>
void foo(funT function_to_call) {
  auto data = bar<typename std::result_of<decltype(function_to_call)&()>::type>();
  //...
}

LIVE DEMO

您还可以通过以下方式使用可变参数模板进一步泛化以接受任何类型的函数及其输入参数:

template <typename funT, typename ...Args>
void foo(funT function_to_call, Args... args) {
  auto data = bar<typename std::result_of<funT(Args...)>::type>();
  ...
}

LIVE DEMO

【讨论】:

  • 这和只使用decltype(function_to_call())有什么区别吗?
  • @Alejandro 是的,因为decltype(function_to_call()) 返回类型为function_to_call(例如int),调用std::result_of&lt;int&gt;::type 会出现编译错误。
  • 我只是在谈论用decltype(function_to_call()) 替换typename std::result_of&lt;funT(Args...)&gt;::type。事实上,它确实有效!查看this live demo
  • @Alejandro 对不起,我虽然你指的是typename std::result_of&lt;decltype(function_to_call())&gt;::type,但我不知道有没有?
  • 一般来说,它们不会做同样的事情,因为result_of 有一些关于指向成员函数类型的特殊规则。但是,只有当您至少有一个论点时,这才有意义。此外,根据您使用result_of 的方式,正确处理具有operator() 的左值/右值限定重载的函子有时会有点棘手或更令人困惑。不过,在这里的具体情况下,我相信它们是等价的。
【解决方案2】:

除了像其他人建议的那样使用result_of,您还可以使用decltype

对于function_to_call不接受参数的情况,可以这样做:

auto data = bar<decltype(function_to_call())>();

但是,对于更一般的情况,正如@101010 所指出的,您可以让您的函数接受任意数量的参数。生成的代码如下所示:

template <typename funT, typename ...Args>
void foo(funT function_to_call, Args&&... args) 
{
   auto data = bar<decltype(function_to_call(std::forward<Args>(args)...))>();
}

对于我尝试过的情况,decltypestd::result_of 在返回正确类型方面具有相同的功能,如果传入的函数类型不是指向成员的指针,如 @hvd指出。通过查看 g++ 源代码,std::result_of 通常在上述情况下以 decltype 的形式实现。

虽然 C++14 std::result_of_t 选项也很有吸引力,但对我来说,使用它似乎比 typename std::result_of&lt;...&gt;::type 选项更简洁、更易读。

【讨论】:

    【解决方案3】:

    您可以使用typename std::result_of&lt;funT()&gt;::type 来满足您的需求,如果您可以访问 C++14,则可以使用 std::result_of_t&lt;funT()&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-06
      • 1970-01-01
      • 2021-12-11
      • 2021-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多