给定一个非常简单但冗长的函数,例如:
int foo(int a, int b, int c, int d) {
return 1;
}
// using ReturnTypeOfFoo = ???
在不重复函数的参数类型的情况下,在编译时确定函数的返回类型(ReturnTypeOfFoo
,在本例中为:int
(最简单、最简洁的方法是什么?
您可以在这里使用std::function
,它将为函数返回类型提供一个别名。这确实需要C++17的支持,因为它依赖于类模板参数推导,但它可以与任何可调用类型一起使用:
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)>;
此技术仅在函数未过载或函数未定义多个operator()
的情况下有效。
最简单简洁的可能是:
template <typename R, typename... Args>
R return_type_of(R(*)(Args...));
using ReturnTypeOfFoo = decltype(return_type_of(foo));
请注意,这不适用于函数对象或指向成员函数的指针。只是没有重载的函数、模板或noexcept
。
但是,如果需要的话,可以通过添加return_type_of
的更多重载来扩展它以支持所有这些情况。
我不知道这是否是最简单的方法(如果你能使用C++17,那肯定不是:请参阅NathanOliver的答案(,但是。。。如何声明一个函数如下:
template <typename R, typename ... Args>
R getRetType (R(*)(Args...));
并使用CCD_ 7?
using ReturnTypeOfFoo = decltype( getRetType(&foo) );
注意,getRetType()
只被声明而没有被定义,因为它只被调用为decltype()
,所以只有返回的类型是相关的。
几年后,您可能会对我自己的(免费(解决方案感兴趣(生产级,完全文档化(。这是您在这里看到的其他一些想法的完整实现(请参阅Barry和max66的回复(。然而,您几乎可以针对函数的任何内容(在C++本身的限制范围内(,而不仅仅是返回类型。
下载代码,添加";TypeTraits.h";以及";编译器版本.h"对于您的项目,然后执行以下操作(注意,您不必显式地#包含"CompilerVersions.h",它会自动#包含在"TypeTraits.h"中(
#include "TypeTraits.h"
using namespace StdExt; // Everything's in this namespace
using ReturnTypeOfFoo = ReturnType_t<decltype(foo)>;