在C++中调用lambda的哪种方式最惯用?

Ele*_*fee 10 c++ lambda function-pointers

我注意到lambda既使用函数指针也function使用专用类型g++.

#include <functional>

typedef int(*fptr)(int, int);

int apply_p(fptr f, int a, int b) {
  return f(a, b);
}

int apply_f(std::function<int(int, int)> f, int a, int b) {
  return f(a, b);
}

void example() {
  auto add = [](int a, int b) -> int {
    return a + b;
  };

  apply_p(add, 2, 3); // doesn't give an error like I'd expect it to
  apply_f(add, 2, 3); 
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:哪些是最常用的?使用一个而不是另一个有什么危险和/或好处?

Mik*_*our 10

我注意到lambdas都使用函数指针和专用function类型

如果lambda没有捕获任何东西,那么它可以衰减为函数指针.

哪些是最惯用的?

都不是.使用function,如果你想存储的任意调用对象.如果您只想创建和使用一个,请保持通用:

template <typename Function>
int apply(Function && f, int a, int b) {
     return f(a,b);
}
Run Code Online (Sandbox Code Playgroud)

你可以进一步使返回和参数类型通用; 我会把它留作练习.

使用一个而不是另一个有什么危险和/或好处?

函数指针版本仅适用于(非成员或静态)函数和非捕获lambdas,并且不允许传递任何状态; 只有函数本身及其参数.该function类型可以包含任何可调用的对象类型,有或没有状态,因此通常更有用.但是,这有一个运行时成本:隐藏包装类型,调用它将涉及虚函数调用(或类似); 并且可能需要动态内存分配来保存大型类型.

  • @ElectricCoffee:我没有看到任何危险,它肯定不会失去*所有*类型的安全.它允许使用`f(a,b)`是可以转换为`int`的格式良好的表达式的任何类型.其他类型将被拒绝. (3认同)