是否可以找出 lambda 的参数类型和返回类型? [英] Is it possible to figure out the parameter type and return type of a lambda?
问题描述
给定一个 lambda,是否可以确定它的参数类型和返回类型?如果是,如何?
Given a lambda, is it possible to figure out it's parameter type and return type? If yes, how?
基本上,我想要 lambda_traits
可以通过以下方式使用:
Basically, I want lambda_traits
which can be used in following ways:
auto lambda = [](int i) { return long(i*10); };
lambda_traits<decltype(lambda)>::param_type i; //i should be int
lambda_traits<decltype(lambda)>::return_type l; //l should be long
背后的动机是我想在接受 lambda 作为参数的函数模板中使用 lambda_traits
,并且我需要知道它在函数内部的参数类型和返回类型:
The motivation behind is that I want to use lambda_traits
in a function template which accepts a lambda as argument, and I need to know it's parameter type and return type inside the function:
template<typename TLambda>
void f(TLambda lambda)
{
typedef typename lambda_traits<TLambda>::param_type P;
typedef typename lambda_traits<TLambda>::return_type R;
std::function<R(P)> fun = lambda; //I want to do this!
//...
}
暂时,我们可以假设 lambda 只接受一个参数.
For the time being, we can assume that the lambda takes exactly one argument.
最初,我尝试使用 std::function
作为:
Initially, I tried to work with std::function
as:
template<typename T>
A<T> f(std::function<bool(T)> fun)
{
return A<T>(fun);
}
f([](int){return true;}); //error
但它显然会出错.所以我把它改成了TLambda
版本的函数模板,想在函数内部构造std::function
对象(如上图).
But it obviously would give error. So I changed it to TLambda
version of the function template and want to construct the std::function
object inside the function (as shown above).
推荐答案
有趣,我刚刚写了一个 function_traits
实现基于 在 C++0x 中专门化一个 lambda 的模板 可以给出参数类型.如该问题的答案所述,诀窍是使用 lambda 的 operator()
的 decltype
.
Funny, I've just written a function_traits
implementation based on Specializing a template on a lambda in C++0x which can give the parameter types. The trick, as described in the answer in that question, is to use the decltype
of the lambda's operator()
.
template <typename T>
struct function_traits
: public function_traits<decltype(&T::operator())>
{};
// For generic types, directly use the result of the signature of its 'operator()'
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
enum { arity = sizeof...(Args) };
// arity is the number of arguments.
typedef ReturnType result_type;
template <size_t i>
struct arg
{
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
// the i-th argument is equivalent to the i-th tuple element of a tuple
// composed of those arguments.
};
};
// test code below:
int main()
{
auto lambda = [](int i) { return long(i*10); };
typedef function_traits<decltype(lambda)> traits;
static_assert(std::is_same<long, traits::result_type>::value, "err");
static_assert(std::is_same<int, traits::arg<0>::type>::value, "err");
return 0;
}
请注意,此解决方案不适用于像 [](auto x) {}
这样的泛型 lambda.
Note that this solution does not work for generic lambda like [](auto x) {}
.
这篇关于是否可以找出 lambda 的参数类型和返回类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!