【问题标题】:Simplest way to determine return type of function确定函数返回类型的最简单方法
【发布时间】:2019-05-09 10:49:22
【问题描述】:

给定一个非常简单但冗长的函数,例如:

int foo(int a, int b, int c, int d) {
    return 1;
}

// using ReturnTypeOfFoo = ???

在编译时确定函数的返回类型(ReturnTypeOfFoo,在本例中为:int)最简单、最简洁的方法是什么无需重复函数的参数类型(仅按名称,因为已知该函数没有任何额外的重载)?

【问题讨论】:

  • 取决于编译器或您可用的支持库...docs.microsoft.com/en-us/cpp/cpp/attributes?view=vs-2017,可以肯定的是,Concepts 也有一些 API 允许您在运行时或编译时推断此信息。跨度>
  • 可能是decltype(foo)::result_type?
  • @ThomasLang 这是从哪里来的? decltype(foo) 是一个没有 result_type 成员的函数,还是我错过了什么?
  • @user463035818 你可能就在这里,我指的是std::function 类型的result_type 成员。

标签: c++ function c++17 return-type compile-time


【解决方案1】:

您可以在此处使用std::function,这将为您提供函数返回类型的别名。这确实需要 C++17 支持,因为它依赖于 class template argument deduction,但它适用于任何可调用类型:

using ReturnTypeOfFoo = decltype(std::function{foo})::result_type;

我们可以让它更通用一点

template<typename Callable>
using return_type_of_t = 
    typename decltype(std::function{std::declval<Callable>()})::result_type;

然后让你像使用它一样

int foo(int a, int b, int c, int d) {
    return 1;
}

auto bar = [](){ return 1; };

struct baz_ 
{ 
    double operator()(){ return 0; } 
} baz;

using ReturnTypeOfFoo = return_type_of_t<decltype(foo)>;
using ReturnTypeOfBar = return_type_of_t<decltype(bar)>;
using ReturnTypeOfBaz = return_type_of_t<decltype(baz)>;

【讨论】:

  • 非常紧凑!我可以确认单行也适用于模板方法,只要指定了所有模板参数。
【解决方案2】:

我不知道是否是最简单的方法(如果你可以使用 C++17 肯定不是:请参阅 NathanOliver 的答案)但是......如何声明一个函数如下:

template <typename R, typename ... Args>
R getRetType (R(*)(Args...));

并使用decltype()?

using ReturnTypeOfFoo = decltype( getRetType(&foo) );

请注意,getRetType() 仅被声明而未定义,因为仅调用了 decltype(),因此只有返回的类型是相关的。

【讨论】:

    【解决方案3】:

    最简单明了的大概是:

    template <typename R, typename... Args>
    R return_type_of(R(*)(Args...));
    
    using ReturnTypeOfFoo = decltype(return_type_of(foo));
    

    请注意,这不适用于函数对象或指向成员函数的指针。只是没有重载或模板的函数,或noexcept

    但如果需要,可以通过添加更多 return_type_of 重载来扩展以支持所有这些情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-18
      • 2012-10-27
      • 1970-01-01
      • 2010-11-11
      • 2019-06-06
      • 1970-01-01
      相关资源
      最近更新 更多