c++ - 函数到 Lambda

标签 c++ templates c++11 c++14

在 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/

相关文章:

c++ - 进程 "mingw32-make.exe"崩溃错误

c++ - 混合别名和模板特化

c++ - 配置文件解析器只返回以前的值

c++ - 使用模板别名(类型别名,使用)弃用模板化类名?

javascript - ListView 与 NumericTextBox 数据初始化

lambda - 用于传递成员函数的 C++0x lambda 包装器与绑定(bind)

c++ - constexpr 构造函数中不能使用 constexpr 构造函数

c++ - 接口(interface)的延迟实现

c++ - 使用 SIGSEGV 或 SIGABRT 信号转储核心并终止进程

c++ - Qt 安全删除设备