找出函数,lambda或函数的返回类型 [英] Finding out the return type of a function, lambda or function
问题描述
这似乎是在这个问题。但那一个是2011年的答案,我正在寻找一个一般情况:lambdas,常规函数和函子。并且,如果可能,通过最现代的c ++语言添加。 (注意: g ++ -std = c ++ 1y test.cpp
)。
This seems to be solved for the case of lambdas in this question. But that one is a 2011 answer and I'm looking for a general case: lambdas, regular functions, and functors. And, if possible, by means of the most modern c++ language additions. (Note: g++ -std=c++1y test.cpp
).
或lambda),我试图找出它的返回类型是什么。例如,声明一个变量(简化情况)。
So, given a function (or a lambda), I'm trying to find out what its return type is. For instance, to declare a variable (simplified case).
using namespace std;
template<typename F>
void test (F h) {
// any of the following should be equivalent to int a; int b; int c;
decltype(h) a; // <<<<< wrong
result_of(h) b; // <<<<<< wrong
result_of<decltype(h)> c; // <<<<<< wrong
}
int a_function (int i) {
return 2*i;
}
int main () {
test (a_function);
}
感谢。
推荐答案
假设:
- 只需要返回类型。
- 你不知道什么是/将是参数的类型(因此
decltype()
或std :: result_of< $ $ $ c $> $
是一个选项。
- 作为参数传递的functor对象不会有重载或通用
c>。
- You want only the return type.
- You don't know what are/will be the types of arguments (so neither
decltype()
norstd::result_of<>
is an option. - The functor object passed as argument will not have an overloaded or generic
operator()
.
那么你可以使用下面的trait来推断任何函子对象的返回类型:
then you can use the below trait that infers the return type of any functor object:
template <typename F>
struct return_type_impl;
template <typename R, typename... Args>
struct return_type_impl<R(Args...)> { using type = R; };
template <typename R, typename... Args>
struct return_type_impl<R(Args..., ...)> { using type = R; };
template <typename R, typename... Args>
struct return_type_impl<R(*)(Args...)> { using type = R; };
template <typename R, typename... Args>
struct return_type_impl<R(*)(Args..., ...)> { using type = R; };
template <typename R, typename... Args>
struct return_type_impl<R(&)(Args...)> { using type = R; };
template <typename R, typename... Args>
struct return_type_impl<R(&)(Args..., ...)> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...)> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...)> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) &> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) &> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) &&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) &&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) const> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) const> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) const&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) const&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) const&&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) const&&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) volatile> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) volatile> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) volatile&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) volatile&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) volatile&&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) volatile&&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) const volatile> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) const volatile> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) const volatile&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) const volatile&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) const volatile&&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) const volatile&&> { using type = R; };
template <typename T, typename = void>
struct return_type
: return_type_impl<T> {};
template <typename T>
struct return_type<T, decltype(void(&T::operator()))>
: return_type_impl<decltype(&T::operator())> {};
template <typename T>
using return_type_t = typename return_type<T>::type;
测试:
#include <type_traits>
template <typename F>
void test(F h)
{
static_assert(std::is_same<return_type_t<F>, int>{}, "!");
return_type_t<F> i = 1;
}
int function(int i) { return 2*i; }
int c_varargs_function(...) { return 1; }
struct A
{
int mem_function(double, float) { return 1; }
};
int main()
{
// Function
test(function);
// C-style variadic function
test(c_varargs_function);
// Non-generic lambda
test([](int i) { return 2*i; });
// Member function
test(&A::mem_function);
}
这篇关于找出函数,lambda或函数的返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!