【问题标题】:Deducing the return type of a standalone function推导出独立函数的返回类型
【发布时间】:2015-05-19 13:22:30
【问题描述】:

我正在尝试找出非成员函数的返回类型。我首先认为std::result_of 可以完成这项工作,但看起来后者仅适用于可调用对象。特别是std::result_of<decltype(f)>::typeis not working。我终于设法想出了一些有效的代码

#include <iostream>
#include <typeinfo>

void f(int); // we deduce the returning type of this function

template<typename Ret, typename... Args>
struct Helper
{
    using type = Ret;
};

template<typename Ret, typename... Args>
Helper<Ret, Args...> invoke(Ret(*fp)(Args...))
{
    return {};
}

template<typename Ret, typename... Args>
using Return_Type = typename Helper<Ret, Args...>::type;

int main()
{
    std::cout << typeid(decltype(invoke(f))::type).name() << std::endl; // fine
}

我在这里使用了一个额外的函数,模板invoke,它接受一个指向我要推断返回类型的函数的指针,并返回一个“帮助器”结构,我从中读取实际的返回类型。

代码看起来有点复杂,因为它涉及一个调用函数(尽管没有执行实际的评估)。还有其他更简单、更清晰/更短的方法吗?

【问题讨论】:

  • 我猜你不想使用decltype(f(0))
  • 不,因为f 可以有可变/未知数量的参数,并且希望某些功能适用于任何功能。
  • result_of 可以很好地处理函数指针。 result_of&lt;decltype(&amp;f)(int)&gt;::typevoid。您只是使用不当,目的不同。
  • @Yakk 可能我的问题不是很清楚。我想仅从名称推断返回类型,而不必指定参数列表。

标签: c++ templates c++11


【解决方案1】:

咨询我自己的old blog posting 关于这个,我发现:

template< class Func >
struct ResultOf
{
    typedef typename std::function<
        typename std::remove_pointer<Func>::type
        >::result_type T;
};

【讨论】:

  • 太棒了!我完全错过了我可以将它包装成 std::function 并使用后者来处理类型的事实。
  • std::function 没有 SFINAE 保证,这使得上述内容成为一个简短的 pretry hack。当然,大多数从函数中提取返回值而不关心它们是如何被调用的代码也是如此。 ;)
  • @Yakk:这听起来像是高度赞扬,在这种情况下,它应该针对 SO 上的 potatoswatter (David Krauss)。如果是负面的批评,那都是我的错。我不得不承认,我不完全明白你在说什么。 ;-)
【解决方案2】:
template<typename>
struct return_t_impl;

template<typename Ret, typename... Args>
struct return_t_impl <Ret(Args...)> 
{
   using type = Ret;
};

template<typename Ret, typename... Args>
struct return_t_impl<Ret(*)(Args...)> : return_t_impl<Ret(Args...)> {};

template<typename T>
using return_t = typename return_t_impl<T>::type;

并将其用作:

using type = return_t<decltype(f)>; //type is void

【讨论】:

  • 谢谢,我错过了我可以定义部分专业化的事实。
  • 第二专精看起来很傻?只需&lt;T*&gt;:return_t_impl&lt;T&gt;{}?
  • 第二个特化是针对auto fptr = f; using type = return_t&lt;decltype(fptr)&gt;;等案例。在这种情况下,fptr 被推断为指向函数的类型,而不仅仅是函数类型。
【解决方案3】:
template<class F>
using return_t = typename std::function<std::remove_pointer_t<std::decay_t<F>>>::result_type;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    相关资源
    最近更新 更多