给定一个lambda,是否可以找出它的参数类型和返回类型?如果有,怎么样?
基本上,我想要lambda_traits哪些可以用于以下方式:
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
Run Code Online (Sandbox Code Playgroud)
背后的动机是我想lambda_traits在一个接受lambda作为参数的函数模板中使用,我需要知道它的参数类型和函数内部的返回类型:
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!
//...
}
Run Code Online (Sandbox Code Playgroud)
目前,我们可以假设lambda只接受一个参数.
最初,我尝试使用std::function:
template<typename T>
A<T> f(std::function<bool(T)> fun)
{
return A<T>(fun);
}
f([](int){return true;}); //error
Run Code Online (Sandbox Code Playgroud)
但它显然会给出错误.所以我将其更改TLambda为函数模板的版本,并希望在函数std::function内部构造对象(如上所示).
鉴于以下代码,模糊性背后的原因是什么?我可以绕过它还是我必须保持(讨厌的)显式演员?
#include <functional>
using namespace std;
int a(const function<int ()>& f)
{
return f();
}
int a(const function<int (int)>& f)
{
return f(0);
}
int x() { return 22; }
int y(int) { return 44; }
int main()
{
a(x); // Call is ambiguous.
a(y); // Call is ambiguous.
a((function<int ()>)x); // Works.
a((function<int (int)>)y); // Works.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,如果我a()用function<int ()>参数注释掉函数并a(x)在我的main中调用,则编译正确失败,因为它们之间的类型不匹配x和function<int (int)>唯一a()可用函数的参数.如果编译器在这种情况下失败,为什么在存在这两个a()函数时会有任何歧义?
我试过VS2010和g ++ v.4.5.两者都给我完全相同的歧义.
假设我有以下函数,它将函数作为参数.
template <typename F>
void test_func(F f)
{
// typedef typename function_traits<F>::return_type T;
typedef int T;
std::mt19937 rng(std::time(0));
std::uniform_int_distribution<T> uint_dist10(0, std::numeric_limits<T>::max());
f(uint_dist10(rng), uint_dist10(rng)); // Problem!
}
Run Code Online (Sandbox Code Playgroud)
用法是:
int foo(int, int) { return 0; }
int bar(int, int, int, int) { return 0; }
int main()
{
test_func(foo);
// test_func(bar);
}
Run Code Online (Sandbox Code Playgroud)
就像foo和bar,我有几个返回的函数T,并采取一些类型的参数T.我想test_func生成尽可能多的调用我的RNG,因为函数f需要参数.换句话说,我们可以假设T始终是整数类型,并且每个参数将是相同的,即对RNG的函数调用.
使用function_traits(比如Boost中的那些),我可以获取返回类型F,这有点帮助.粗略地说,我的问题是
如何生成所需数量的函数调用,使其与函数F的arity匹配?
在C++ 11之前,我会看一下Boost.Preprocessor,或者可能依赖于模板专业化.现在有更好的方法吗?