在 C++ 中,使用 lambda 表达式和函数对象(而不是函数指针)通常很有用。原因是 lambda 或函数对象的类型完全编码所调用的内容(因此允许内联),而函数指针的类型仅对签名进行编码。我有一个有趣的想法,当使用通用代码创建调用给定函数的 lambda 时,它可能会很有用。换句话说,给定指定函数的高阶函数会返回调用该函数的 lambda。为了避免任何间接寻址,必须使用函数指针非类型模板参数。问题是,要指定这样的非类型模板参数,您必须知道函数的签名。我无法避免需要两次传递有问题的函数:一次是为了推导类型,一次是为了实际专门研究该函数。我最好的尝试如下:
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)...);
};
}
};
要使用它,您需要执行以下操作:
void f(int, int) { std::cerr << "f\n"; };
...
auto lam = makeLambdaHelper<decltype(&f)>::blah<f>();
lam(0,0);
当 f 的类型作为模板参数传递给 makeLambdaHelper 时,首先会推导出它的签名。然后该结构体有一个声明非类型模板参数的静态函数;所以我们传递 f 本身,并得到一个 lambda。像这样必须通过 f 两次是相当难看的;是否可以做得更好,也许通过使用默认模板参数做一些巧妙的事情?
最佳答案
如果您只想将函数指针包装在函数对象中,我建议使用宏:
#define WRAP_FN(f) [](auto&&... args) -> decltype(auto) { \
return f(std::forward<decltype(args)>(args)...); };
使用方式如下:
auto lam = WRAP_FN(foo);
该宏的优点是它会另外处理重载名称 - 这样您就可以将重载函数传递到 std 算法中并让它执行您想要的操作。
关于c++ - 函数到 Lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35783785/