

新闻资讯
技术学院std::function 用于存储任何符合指定签名的可调用对象,如普通函数、lambda、成员函数指针或 std::bind 结果;需严格匹配参数与返回类型,捕获局部变量时须注意生命周期,空对象调用抛 std::bad_function_call。
std::function 是一个类型擦除的可调用对象包装器,能存任何符合签名的可调用物:普通函数、lambda、成员函数指针、std::bind 结果。它不自己执行逻辑,只提供统一接口调用。
关键点是「签名必须匹配」——比如声明为 std::function,就只能存接受 double、返回 int 的东西。传错类型编译直接报错,不是运行时崩溃。
const 或引用)std::function 在函数外被调用,就是悬垂指针std::function 调用会抛 std::bad_function_call,用前建议判空:if (cb) cb(42);
绑定成员函数必须显式传入对象(或指针),因为 this 不是自动附带的。常见错误是写成 std::bind(&MyClass::func, arg1) —— 缺了对象实例,编译不过。
参数占位符用 _1、_2 等(需 #include ),它们代表调用时传入的位置参数;固定参数直接写在 std::bind 参数列表里。
class Printer {
public:
void print(int x, const std::string& s) { std::cout << x << ": " << s << "\n"; }
};
Printer p;
auto bound = std::bind(&Printer::print, &p, 42, _1); // 固定 this 和第一个参数,_1 占位第二个
bound("hello"); // 输出 "42: hello"
std::ref(obj) 绑定可变对象,避免拷贝;否则绑定的是副本,修改不影响原对象std::bind(func, std::string("tmp")),临时对象在 bind 返回后就销毁,调用时读到的是垃圾std::bind 对完美转发支持有限,复杂场景推荐直接用 lambda最典型问题是签名不一致:比如成员函数是 ,但你绑定了两个固定参数,剩下 0 个可调用参数,那目标
void (int, int)std::function 类型就得是 std::function,而不是原函数签名。
另一个坑是 std::bind 返回类型不可名状(unspecified type),必须靠 std::function 接住,不能用 auto 存然后二次赋值——除非你只用一次,且不跨作用域。
std::functiontask = std::bind(&Printer::print, &p, 99, "done"); task(); // OK // 错误写法(类型不匹配): // std::function bad = std::bind(&Printer::print, &p, 99, "done"); // 编译失败:bind 结果调用时不接受 int 参数
std::function 声明的参数个数一致std::bind 是一次性构造,要动态改就得换 lambda 或用对象封装状态绝大多数简单回调场景,lambda 更直观、性能更好(无类型擦除开销)、生命周期更可控。只有两种情况才倾向 std::bind:
std::function 变量(lambda 每次定义类型都不同,无法赋值给同一变量)std::bind(f, _2, _1) 把调用顺序翻转——lambda 写起来啰嗦些但注意:lambda 捕获 this 要明确写 [this],否则无法访问成员;而 std::bind 绑定成员函数时,this 是作为第一个参数传的,语义更接近传统 C 风格回调注册。
真正容易被忽略的是:std::function 的拷贝构造有潜在堆分配(内部存储大对象时),高频回调场景若对性能敏感,得评估是否值得用;而 lambda 若不捕获,通常能内联,std::bind 几乎不可能内联。