bind函数绑定器bind也是仿函数类的实例将目标函数调用的参数提前占位placeholder: :_N在bind的仿函数被调用时传入的第n个实参替换。头文件#includefunctional语法function返回类型参数表名称函数名或lambda本质bind是一个模板函数返回一个可调用对象仿函数占位符std::placeholders::_1, _2, _3...表示调用时再传入的参数int main() { auto add [](int a, int b) { cout a a b b endl; return a b; }; cout add(10, 5) endl;//二元仿函数 //绑定第一个参数 auto _add bind(add,placeholders::_1 ,21); cout _add(100) endl; //绑定第二个参数 auto _add bind(add, 21,placeholders::_2); cout _add(100,99,88,77) endl; auto gt [](int a, int b) {return a b; }; cout boolalpha gt(100, 99) endl; auto _gt bind(gt, placeholders::_1, 50); cout boolalpha _gt(45) endl; return 0; }算法实践顺序变更int main() { vector intv{ 3,2,1,9,7,5,6 }; for_each(v.begin(), v.end(), [](int v) {cout v ; }); cout endl; reverse(v.begin(), v.end());//反转 for_each(v.begin(), v.end(), [](int v) {cout v ; }); cout endl; //随机打乱 random_shuffle(v.begin(), v.end()); for_each(v.begin(), v.end(), [](int v) {cout v ; }); cout endl; return 0; }排序算法内部通常使用内省排序快速排序作为主体算法堆排序当递归深度过深时接管插入排序对小规模子数组使用特点不稳定性相等元素的相对顺序排序后可能被打乱时间复杂度保证C11起强制要求Onlogn要求随机访问迭代器vectordeque原地排序不需要什么空间原地排序int main() { vectorintv(10); srand(time(NULL)); auto gen [] { return rand() % 100 1; }; generate(v.begin(), v.end(), gen); auto show [](int v) { cout v ; }; for_each(v.begin(), v.end(), show); cout endl; //排序 sort(v.begin(), v.end());//升序 for_each(v.begin(), v.end(), show); cout endl; //要求比较的仿函数时二元谓词 sort(v.begin(), v.end(),greater());//降序 for_each(v.begin(), v.end(), show); cout endl; //sort_heap()//堆排序 return 0; }sort不稳定排序 相等元素原来的前后顺序会乱。stable_sort稳定排序 相等元素原来的前后顺序 100% 保持不变。class Person { int pid; int age; string name; public: Person(int pid, int age, string name) :pid(pid), age(age), name(name) {} bool operator(const Person p) const { return age p.age; // 按人员中的年龄进行比较 } friend ostream operator(ostream out, Person p) { cout pid: p.pid , Name: p.name , Age: p.age endl; return out; } int _pid() const { return pid; } const string _name() const { return name; } using byFunc bool (*)(const Person left, const Person right); static byFunc byNameSort() { return [](const Person left, const Person right) { return left.name right.name; }; } static byFunc byPidSort() { return [](const Person left, const Person right) { return left.pid right.pid; }; } }; int main() { vectorPerson v; v.push_back(Person(5, 20, 王一)); v.push_back(Person(1, 18, 刘一)); v.push_back(Person(24, 19, 张一)); v.push_back(Person(7, 20, 吴一)); v.push_back(Person(6, 20, 严一)); v.push_back(Person(3, 18, 康一)); v.push_back(Person(15, 19, 墨一)); v.push_back(Person(25, 18, 刘二)); v.push_back(Person(35, 17, 王麻子)); for_each(v.begin(), v.end(), [](Person p) { cout p; }); // sort_heap(v.begin(), v.end()); // vector not heap //sort(v.begin(), v.end()); // ok , age排序 //stable_sort(v.begin(), v.end()); // ok // 按pid排序 /* sort(v.begin(), v.end(), [](const Person left, const Person right) { return left._pid() right._pid(); });*/ // 按name排序 sort(v.begin(), v.end(), Person::byNameSort()); cout string(20, -) 升序 string(20, -) endl;; for_each(v.begin(), v.end(), [](Person p) { cout p; }); return 0; }function函数包装器语法function 返回类型参数表 名称 函数地址使用场景1.为lambda表达式具名2.作为函数形参上的类型//1.函数包装器function #include functional void my_show1(string info) { cout INfo: info endl; } void my_show2(string error) { cout Error: error endl; } //2.作为形参表上的参数类型 void log(string msg,functionvoid(string)logF) { if (logF) logF(msg); } int main() { //1.为lambda表达式具名 functionint (int,int) f [](int a, int b) { return a b; }; cout f(1, 5) endl; functionvoid(string)show; if(show)//验证show是否有效 show(hi,function); show my_show1; show(2026-06-04 19:20:30 Http/CET OK); show my_show2; show(2026-06-04 19:20:30 Http/auth POST 500); log(test1, my_show1); log(test2, my_show2); log(test3, [](string msg) {cout * msg endl; }); return 0; }头文件#include functional面试题C编译器默认为类添加的函数有哪些6个无参构造、拷贝构造、移动构造、拷贝赋值、移动赋值、析构函数移动构造将目标对象的数据转移到当前新对象上目标对象的数据将回收移动语义C移动语义是C11引入的一项核心特性它允许将资源(如堆内存)从一个对象转移给另一个对象而不是进行复制。这可以避免不必要的深拷贝大幅提升程序性能。触发移动语义std::move()移动构造函数类名类名移动赋值重载返回类型 operator(类名)#includeexception class A { int* v; public: A(const int v) { //堆空间的成员 this-v new int(v); } A(const A o) {//拷贝构造 this-v new int(*o.v); } A operator(const A o){//拷贝赋值重载 //防止自己赋值给自己 if (this ! o) { this-v new int(*o.v); } return *this; } A(A o)noexcept {//移动构造函数 //只是将o.v指向的堆空间转给当前对象 this-v o.v; //将o.v指针置空 o.v nullptr; cout A(Ao) v: v endl; } A operator(A o) noexcept{ //将o对象的数据转移到当前对象上 if (v ! nullptr)delete v;//先释放自己的数据空间 v o.v;//将o.v转移过 o.v nullptr; return *this; } int value() { if (v nullptr)throw runtime_error(v 是空指针); return *v; } void value(const int v) { if (this-v nullptr)throw runtime_error(v是空指针); *this-v v; } ~A() { if (v ! nullptr) { delete v; } } }; int main() { A a1(20); A a2 a1;//拷贝构造函数 a2 a2;//拷贝赋值重载 //移动构造函数 A a3 std::move(a2);//将a2的数据转移给a3,a2悬空暂时不能直接使用如果想再次使用a2必须重新赋值 cout a3 value is a3.value() endl; //cout a2 value is a2.value() endl; a3.value(100);//修改值 a1 a3; cout a1 value is a1.value() endl; return 0; }智能指针C 用来自动管理动态内存的工具。封装了原始指针的类利用 RAII资源获取即初始化 机制在对象生命周期结束时自动释放内存不用程序员手动写 delete。自定义智能指针构造函数接收外部指针在析构函数中对指针进行回收重载指针的操作operator-,operator* ...主动回收指针函数reset获取原始指针get/release// 3. 智能指针类模板: RAII(资源获取即初始化) 机制自动管理指针 // 3.1 自定义智能指针类模板 struct Person { int pid; string name; int age; public: Person(int pid, string name, int age):pid(pid),name(name),age(age){} void show() { cout pid | name | age endl; } ~Person() { cout ~Person(): this endl; } }; class AutoPersonPtr { Person* p; public: AutoPersonPtr(Person* p):p(p){} AutoPersonPtr(int pid, string name, int age) { p new Person(pid, name, age); } AutoPersonPtr(const AutoPersonPtr o) delete; void operator(const AutoPersonPtr o) delete; AutoPersonPtr(AutoPersonPtr o) delete; void operator(AutoPersonPtr o) delete; Person * operator-() { return p; } Person operator*() { return *p; } void reset() { if (p ! nullptr) { delete p; p nullptr; } } ~AutoPersonPtr(){ if (p ! nullptr) delete p; // 自动释放指针 } }; int main() { AutoPersonPtr p1(new Person(1, Disen, 20)); AutoPersonPtr p2(3, Jack, 18); p1-show(); p2-show(); (*p1).show(); // 手动释放指针的堆空间 //p1.reset(); //p2.reset(); cout -----main over------ endl; return 0; }进阶将自定义的智能指针提升为类模板//进阶将自定义的智能指针提升为类模板 templateclass T class UniPtr { T* ptr; public: UniPtr(T*ptr):ptr(ptr){} ~UniPtr() { if (ptr ! nullptr)delete ptr; } T* operator-() { return ptr; } T operator*() { return *ptr; } void reset() { if (ptr ! nullptr) { delete ptr; ptr nullptr; } } };C11自带的智能指针unique_ptr唯一智能指针1.独占式智能指针 —— 同一时间只能有一个 unique_ptr 管理这块内存2.不能拷贝只能移动3.性能 原生指针没有额外开销4.出作用域自动 delete绝对不会内存泄漏。因为unique_ptr是独占式智能指针因此有一个指针不能放在两个智能指针下shared_ptr共享智能指针1.shared_ptr 靠引用计数管理内存计数 0 才释放2.优先用 make_sharedT() 创建不要用 new3.可以随意拷贝、赋值4.循环引用 → 用 weak_ptr 解决引用计数式原子操作多线程下线程安全基于赋值运算重载实现一个shared_ptr多次赋值每一次赋值都会增加一次引用(内部基于引用计数器)某一个shared_ptr 对象执行reset函数引用计数减一当引用计数为0时则释放原始指针。weak_ptr弱引用智能指针1.不增加引用计数2.不能直接 * 访问不能直接 -3.必须先 lock () 转成 shared_ptr 才能用weak_ptr赋值时不会增加shared_ptr的引用计数可以解决shared_ptr的循环引用问题。每一次使用weak_ptr对原始指针操作必须转成shard_ptrlock(),在调用lock之前必须验证是否过期expired(),返回false。auto_ptrC11之前当前已经被unique取代头文件memory