std::function 是通用可调用对象包装器,能统一存储函数指针、Lambda、函数对象和成员函数,常用于回调;std::bind 用于绑定可调用对象与参数,支持占位符实现偏函数应用;两者结合可灵活处理延迟调用与策略模式。

在c++中,std::function 和 std::bind 是处理可调用对象(callable objects)的重要工具。它们让函数指针、lambda表达式、函数对象和成员函数等统一以一致的方式被存储和调用。下面详细说明它们的使用方法和典型场景。
std::function:通用可调用对象包装器
std::function 是一个类模板,可以封装任何可调用目标——只要签名匹配。它常用于回调函数、事件处理或需要延迟执行的场合。
基本语法:
定义一个接受特定参数并返回特定类型的可调用对象:
立即学习“C++免费学习笔记(深入)”;
std::function<返回类型(参数类型...)>
常见用法示例:
- 封装普通函数
- 绑定 lambda 表达式
- 保存函数对象(仿函数)
- 作为回调参数传递
代码示例:
#include <functional> #include <iostream> <p>double add(double a, double b) { return a + b; }</p><p>int main() { std::function<double(double, double)> op = add; std::cout << op(3.0, 4.0) << "n"; // 输出 7</p><pre class='brush:php;toolbar:false;'>op = [](double a, double b) { return a * b; }; std::cout << op(3.0, 4.0) << "n"; // 输出 12
}
可以看到,同一个 std::function 变量可以先后绑定普通函数和 lambda,只要签名一致。
std::bind:函数绑定与参数占位
std::bind 用于将一个可调用对象与其参数绑定,生成一个新的可调用对象。它可以预先固定部分参数,实现“偏函数应用”(partial application)。
基本语法:
std::bind(可调用对象, 参数1, 参数2, ...)
其中参数可以是具体值,也可以是占位符(如 std::placeholders::_1)。
关键点:
- 占位符表示将来调用时传入的实际参数
- 支持绑定成员函数,需传入对象实例
- 可绑定多个参数,顺序由占位符决定
绑定普通函数并固定部分参数:
#include <functional> #include <iostream> <p>void print_sum(int a, int b) { std::cout << "Sum: " << a + b << "n"; }</p><p>int main() { auto f1 = std::bind(print_sum, 10, std::placeholders::_1); f1(5); // 相当于 print_sum(10, 5),输出 Sum: 15 }</p>
这里 _1 表示调用 f1 时传入的第一个参数,a 被固定为 10。
绑定成员函数
绑定成员函数时,第一个参数通常是对象指针或引用,后面是成员函数的参数。
示例:
struct Calculator { int multiply(int x, int y) { return x * y; } }; <p>int main() { Calculator calc; auto func = std::bind(&Calculator::multiply, &calc, std::placeholders::_1, std::placeholders::_2); std::cout << func(3, 4) << "n"; // 输出 12 }</p>
注意:&Calculator::multiply 是成员函数指针,&calc 提供调用实例。
如果使用对象副本而非指针:
auto func = std::bind(&Calculator::multiply, calc, _1, _2);
此时会拷贝 calc,适合无状态对象。
与 std::function 配合使用
std::bind 返回的是一个未命名的函数对象,通常无法直接声明变量接收(类型复杂),但可以用 std::function 统一管理。
示例:
std::function<int(int, int)> bound_mul = std::bind(&Calculator::multiply, &calc, _1, _2); bound_mul(5, 6); // 正常调用
这种组合非常灵活,尤其适合注册回调、延迟执行或策略模式。
基本上就这些。std::function 提供统一接口,std::bind 实现参数绑定,两者结合能写出更清晰、可复用的代码。不复杂但容易忽略细节,比如占位符顺序和对象生命周期。


