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;
}
|
参考