std::function类模板:是一个抽象的函数参数以及函数返回值的类模板
#include <iostream>
#include <functional> // 需要包含此头文件
using namespace std;
int add(int a, int b) {
return a + b;
}
int main() {
std::function<int(int, int)> func = add; //表示返回 int,接受两个 int 参数的函数。
cout << func(3, 5) << endl; // 输出 8
}
抽象:把任意函数包装成一个对象,该对象可以保存、传递以及复制。动态绑定,只需修改该对象(赋值不同的function对象),实现类似多态的效果
用途:1、保存普通函数,类的静态成员函数。2、保存仿函数。3、保存类成员函数4、保存lambda表达式5、保存bind返回的函数对象
仿函数(函数对象):重载了操作符()的类,可以有状态,通过成员变量进行存储状态。有状态的
class Add { // 定义一个仿函数类
public:
int operator()(int a, int b) { // 重载 () 使对象可调用
return a + b;
}
};
int main() {
Add add; // 创建仿函数对象,Add 类重载了 operator(),所以 add(3, 5) 看起来像函数调用,但本质是对象调用 operator()
cout << add(3, 5) << endl; // 调用仿函数,输出 8
}
lambda表达式:一种方便创建匿名对象的语法糖
基本语法:[捕获列表](参数列表) -> 返回类型 { 函数体 }
int main() {
auto add = [](int a, int b) { return a + b; };
cout << add(3, 5) << endl; // 输出 8
}
___________________________________________________________________
int x = 10, y = 20;
auto sum1 = [x, y]() { return x + y; }; // 按值捕获
auto sum2 = [&x, &y]() { return x + y; }; // 按引用捕获
auto sum3 = [=]() { return x + y; }; // 捕获所有变量(按值)
auto sum4 = [&]() { return x + y; }; // 捕获所有变量(按引用)
cout << sum1() << endl; // 输出 30
int a = 10;
auto change = [a]() mutable { a += 5; cout << a << endl; };
change(); // 输出 15
cout << a << endl; // 输出 10(a 没有被真正修改)
_____________________________________________________________________
Lambda 在 std::sort 中作为比较函数
using namespace std;
int main() {
vector<int> v = {5, 2, 8, 1};
// 使用 Lambda 进行降序排序
sort(v.begin(), v.end(), [](int a, int b) { return a > b; });//Lambda 避免额外函数定义,使代码更简洁。
for (int num : v) cout << num << " "; // 输出:8 5 2 1
}
[]捕获列表:1、值捕获,默认只读,不能修改,mutable可读可写,并不会修改外部变量的值
2、引用捕获:可读可写,会修改外部变量的值
3、[]指定函数内部可以访问的外部变量
lambda本质是外部变量将转变为类的成员变量,在编译的时候,将lambda表达式转变为一个函数对象。根据lambda参数列表重载operator()操作符
bind函数适配器:通过绑定函数以及函数参数的方式生成函数对象的模板函数。提供占位符,提供灵活的参数绑定。
基本语法:std::bind(可调用对象, 参数1, 参数2, ...);
#include <iostream>
#include <functional> // 需要包含 std::bind 头文件
using namespace std;
int add(int a, int b) {
return a + b;
}
int main() {
// 绑定 add,并固定一个参数(b=5)
auto add_five = std::bind(add, std::placeholders::_1, 5);
cout << add_five(10) << endl; // 相当于 add(10, 5),输出 15
}
特征:绑定函数以及函数参数构成一个函数对象(闭包),允许修改参数顺序顺序
总结:
function用来描述函数对象的类型;
lambda表达式用来生成函数对象(可以访问外部变量匿名函数);
bind也是用来生成函数对象(函数和参数进行绑定生成函数对象);
注:函数对象就是仿函数