复习:std::function 用法笔记

std::function 可以将函数,函数对象(仿函数),lambda表达式包装成一个对象std::function对象本身可以作为函数参数,并且是可复制的(复制构造、赋值)。

1. 封装函数指针

int add(int a, int b) { return a + b; }

int main() {
  std::function<int(int, int)> f = add;
  int result = f(1, 2);
  std::cout << result << std::endl;
  return 0;
}

2. 封装函数对象(仿函数)

struct Adder {
  int operator()(int a, int b) { return a + b; }
};

int main() {
  Adder adder;
  std::function<int(int, int)> f = adder;
  int result = f(1, 2);
  std::cout << result << std::endl;
  return 0;
}

3. 封装 lambda 表达式

int main() {
  // using func_t = int(int, int);
  std::function<int(int, int)> f = [](int a, int b) { return a + b; };
  int result = f(1, 2);
  std::cout << result << std::endl;
  return 0;
}

4. 与 std::bind 结合使用

int add(int a, int b) { return a + b; }

int main() {
  std::function<int(int)> f = std::bind(add, 1, std::placeholders::_1);
  int result = f(2);
  std::cout << result << std::endl;
  return 0;
}

5. lambda 表达式

lambda表达式是一个匿名函数对象,即编译器会创建一个仿函数( 调用时,调用 operator()(....) ),并将外部捕获的变量,添加到该匿名对象中。这些是lambda的额外开销。

注:在O2编译时,仿函数也会被优化掉,直接编译成跳转代码段。

int main()
{
  // Lambda & auto
  int member=10;
  auto endGame = [=](int a, int b){ return a+b+member;};

  endGame(4,5);

  return 0;

}

展开成:

int main()
{
  int member = 10;

  class __lambda_6_18
  {
    int member;
    public:
    inline /*constexpr */ int operator()(int a, int b) const
    {
      return a + b + member;
    }

    public: __lambda_6_18(int _member)
    : member{_member}
    {}

  };

  __lambda_6_18 endGame = __lambda_6_18{member};
  endGame.operator()(4, 5);

  return 0;
}

参考




    Enjoy Reading This Article?

    Here are some more articles you might like to read next:

  • al-folio 本地部署记录(Ubuntu 24.04)
  • C++ Traits
  • 道格拉斯-普克算法(Douglas–Peucker algorithm)
  • CMake支持库收集
  • QGC代码架构解析:飞行前检查(起飞条件)