在C ++中,通常使用lambda和函数对象而不是函数指针来工作。原因是lambda或函数对象的类型完全对要调用的内容进行编码(从而允许内联),而函数指针的类型仅对签名进行编码。我有一个有趣的想法,当使用通用代码创建调用给定函数的lambda时,它可能会很有用。换句话说,给定指定函数的高阶函数将返回调用它的lambda。为了避免任何间接访问,必须使用函数指针非类型模板参数。问题是要指定这样的非类型模板参数,您必须知道函数的签名。我无法解决需要两次传递有问题的函数的问题:一次推论类型,一次真正专注于函数。我的最佳尝试是这样的:
It's often useful in C++ to work with lambdas and function objects, rather than function pointers. The reason being that a lambda's or function object's type fully encodes what is getting called (and thus allows inlining), whereas a function pointer's type merely encodes the signature. I had the interesting thought that it might be useful when using generic code to create a lambda that calls a given function. In other words, a higher order function that given a specified function, returns a lambda that calls it. To avoid any indirection, function pointer non-type template parameters have to be used. The problem is that to specify such a non-type template parameter, you have to know the signature of the function. I'm not able to get around needing to pass the function in question twice: once to deduce the types, and once to actually specialize on the function. My best attempt looks like this:
template <class T> struct makeLambdaHelper; template <class R, class ... Args> struct makeLambdaHelper<R(*)(Args...)> { template <void(*F)(Args...)> static auto blah() { return [] (Args && ... args) { return F(std::forward<Args>(args)...); }; } };要使用此功能,您可以这样做:
To use this, you would do:
void f(int, int) { std::cerr << "f\n"; }; ... auto lam = makeLambdaHelper<decltype(&f)>::blah<f>(); lam(0,0);将f的类型作为模板参数传递给makeLambdaHelper时,首先推导出其签名。然后该结构具有一个静态函数,该函数声明一个非类型的模板参数。所以我们通过f本身,得到一个lambda。像这样不得不两次通过f是非常丑陋的。是否有可能做得更好,也许可以通过使用默认模板参数做一些聪明的事情?
When f's type is passed as the template argument to makeLambdaHelper, first its signature is deduced. Then the struct has a static function that declares a non-type template parameter; so we pass f itself, and get out a lambda. Having to pass f twice like this is pretty ugly; is it possible to do better, maybe by doing something clever with default template parameters?
推荐答案如果只想包装一个函数指针指向函数对象,建议使用宏:
If you just want to wrap a function pointer in a function object, I'd recommend a macro:
#define WRAP_FN(f) [](auto&&... args) -> decltype(auto) { \ return f(std::forward<decltype(args)>(args)...); };使用方式如下:
auto lam = WRAP_FN(foo);宏的优点是它还会处理重载名称-这样您就可以将重载函数传递到std算法中,并使它们执行您想要的操作。
The advantage of the macro is that it'll additionally handle overloaded names - so that you can pass overloaded functions into std algorithms and have that do what you want it to.
更多推荐
Lambda函数
发布评论