std::function 可以将函数,函数对象(仿函数),lambda表达式包装成一个对象。std::function对象本身可以作为函数参数,并且是可复制的(复制构造、赋值)。
1. 封装函数指针
| 1
2
3
4
5
6
7
8
 | 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. 封装函数对象(仿函数)
| 1
2
3
4
5
6
7
8
9
10
11
 | 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 表达式
| 1
2
3
4
5
6
7
 | 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 结合使用
| 1
2
3
4
5
6
7
8
 | 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编译时,仿函数也会被优化掉,直接编译成跳转代码段。
| 1
2
3
4
5
6
7
8
9
10
11
 | int main()
{
  // Lambda & auto
  int member=10;
  auto endGame = [=](int a, int b){ return a+b+member;};
  endGame(4,5);
  return 0;
}
 | 
展开成:
| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 | 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;
}
 | 
参考