确定函数返回类型的最简单方法

时间:2018-12-07 16:29:41

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

给出了一个非常简单但冗长的功能,例如:

const hasInjectableDecorator = node.decorators && node.decorators.some(
    (decorator) => decorator.kind === SyntaxKind.Decorator
);

在编译时间不重复函数参数类型的情况下,确定函数返回类型(decorator,在本示例中为@Injectable)的最简单明了的方法是什么 (仅命名,因为已知该函数没有任何其他重载)?

3 个答案:

答案 0 :(得分:52)

您可以在此处利用std::function,这将为您提供函数返回类型的typedef。这确实需要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)>;

答案 1 :(得分:21)

最简单明了的可能是:

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

using ReturnTypeOfFoo = decltype(return_type_of(foo));

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

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

答案 2 :(得分:14)

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

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

并使用decltype()

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

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