std::function 是可调用对象的类型擦除容器,非万能函数指针;支持函数指针、lambda、bind 等,但有开销、不可比较、移动后状态未定义。

直接说结论:std::function 不是“万能函数指针”,它本质是可调用对象的类型擦除容器,能存函数指针、lambda、绑定表达式、成员函数指针等,但有开销、不能比较相等、不支持移动后状态检查。
std::function 的声明与基本赋值场景
声明时必须显式指定签名,比如 std::function 表示接受两个 int 参数、返回 int 的可调用对象。常见错误是漏写括号或参数类型不匹配:
- 错:
std::function—— 这行其实对,但若 lambda 捕获了局部变量而没加f = [](int a, int b) { return a + b; }; [&]或[=],编译失败 - 错:
std::function而f = some_function_ptr; some_function_ptr实际是void(*)(int)—— 签名不兼容,直接编译报错 - 正确赋值来源包括:
普通函数指针、无捕获 lambda(自动转为函数指针)、std::bind结果、std::mem_fn或成员函数指针包装体
捕获型 lambda 和 std::function 的内存开销
std::function 内部用小对象优化(SOO),通常前 16–32 字节存在自身对象里;一旦 lambda 捕获大量数据(如大数组、std::string、std::vector),就会触发堆分配。这不是 bug,但容易被忽略:
- 小捕获(如
[x](int y){ return x + y; },其中x是int)—— 通常不堆分配 - 大捕获(如
[data = std::vector)—— 必然堆分配,且拷贝构造(100000)](){ ... } std::function会复制整个 vector - 避免方式:改用引用捕获
[&data](注意生命周期!),或把大数据抽成外部对象,只捕获指针/引用
std::vectorbig_data(100000, 42); auto bad_lambda = [big_data]() { return big_data.size(); }; // 堆分配,拷贝重 auto good_lambda = [&big_data]() { return big_data.size(); }; // 不复制 data,但需确保 big_data 活得比 function 久 std::function f = good_lambda;
std::function 与成员函数指针的绑定
不能直接把成员函数指针赋给 std::function,因为缺少 this。必须绑定实例(或用 std::bind / lambda 包装):
动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包
立即学习“C++免费学习笔记(深入)”;
- 错:
std::function—— 编译失败,“no known conversion”f = &MyClass::do_something; - 对(lambda):
MyClass obj; std::functionf = [&obj]() { obj.do_something(); }; - 对(std::bind):
std::functionf = std::bind(&MyClass::do_something, &obj); - 注意:若用
std::bind绑定临时对象(如std::bind(..., MyClass{})),调用时this悬空,UB
性能敏感场景下 std::function 的替代选择
如果函数调用在 hot path(如循环内、图形渲染每帧调用),std::function 的虚函数调用开销(即使 SOO)和可能的堆访问会影响性能。这时应考虑:
- 模板参数化:把可调用对象作为模板参数传入,让编译器内联(最高效)
- 函数指针:仅限无状态、无捕获的自由函数
- 手动函子(functor)类:定义
operator(),零开销,但失去类型擦除能力 - 别为了“统一接口”强行用
std::function—— 它的便利性是有代价的
真正麻烦的不是怎么写,而是忘记它背后是类型擦除+运行时分发,以及移动后原对象进入有效但未指定状态(不能再次调用,也不能比较)。









