我想知道是否有一种标准方法来获取任何给定lambda参数的类型签名(即返回类型和类型)?
我问的原因是我一直想知道auto
声明中的类型到底是什么auto l =[](int x,int y)->int{return x+y;}
。在的其他用例中auto
,对于较长的类型名称,这是一种方便且较短的替代方法。但是对于lambda,甚至还有另一种方法来声明lambda变量吗?
我的理解是,标准的lambda仅仅是一个函数对象,而是它自己的类型。因此,即使两个lambda具有相同的返回类型和参数类型,它们仍然是两个不同的,不相关的类/函数。但这有没有办法捕捉到它们在类型签名方面相同的事实?
我认为我正在寻找的类型签名可能是std::function<>
正确类型的对象。
一个更有用/更有意义的问题是,如果可以提取类型签名,则可以编写一个通用包装函数,以将任何lambda函数转换为具有std::function
相同类型签名的对象。
根据可以表达lambda表达式的“类型”吗?,实际上,当前的c ++(无需c ++ 1y)有一种简单的方法来计算lambda的return_type和参数类型。为此,为每个lambda组装一个std::function
类型化的签名类型(f_type
以下称)并不困难。
I.使用这种抽象类型,实际上可能有一种替代方法来auto
表示lambda的类型签名,即function_traits<..>::f_type
下面的方法。注意:f_type
并不是Lambda的真实类型,而是功能上Lambda类型签名的摘要。但是,它可能比lambda的实际类型有用,因为每个lambda都是自己的类型。
如下代码所示,就像一个人可以使用vector<int>::iterator_type i = v.begin()
,一个人也可以做function_traits<lambda>::f_type f = lambda
,这是神秘方法的替代方法auto
。当然,这种相似只是形式上的。下面的代码涉及到将lambda转换为a std::function
,这会浪费std::function
对象构造类型的开销,而通过std::function
对象进行间接调用的开销也很小。但是这些std::function
搁置使用的实现问题(我不认为这是根本性的,应该永远存在),毕竟,有可能明确表达任何给定lambda的(抽象)类型签名。
二。还可以编写一个make_function
包装器(非常类似于std::make_pair
和std::make_tuple
),以将lambda f
(以及其他可调用对象,如函数指针/函子)自动转换为std::function
具有相同类型推断功能的。
测试代码如下:
#include <cstdlib>
#include <tuple>
#include <functional>
#include <iostream>
using namespace std;
// For generic types that are functors, delegate to its 'operator()'
template <typename T>
struct function_traits
: public function_traits<decltype(&T::operator())>
{};
// for pointers to member function
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const> {
//enum { arity = sizeof...(Args) };
typedef function<ReturnType (Args...)> f_type;
};
// for pointers to member function
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) > {
typedef function<ReturnType (Args...)> f_type;
};
// for function pointers
template <typename ReturnType, typename... Args>
struct function_traits<ReturnType (*)(Args...)> {
typedef function<ReturnType (Args...)> f_type;
};
template <typename L>
typename function_traits<L>::f_type make_function(L l){
return (typename function_traits<L>::f_type)(l);
}
long times10(int i) { return long(i*10); }
struct X {
double operator () (float f, double d) { return d*f; }
};
// test code
int main()
{
auto lambda = [](int i) { return long(i*10); };
typedef function_traits<decltype(lambda)> traits;
traits::f_type ff = lambda;
cout << make_function([](int i) { return long(i*10); })(2) << ", " << make_function(times10)(2) << ", " << ff(2) << endl;
cout << make_function(X{})(2,3.0) << endl;
return 0;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句