std::bind是C++11标准引入的函数绑定工具,定义在functional头文件中,它的核心作用是把一个可调用对象和若干参数绑定在一起,生成一个新的可调用对象,新的可调用对象调用时会自动传入预先绑定的参数,同时支持用占位符指定后续需要传入的参数位置。

std::bind的基本语法
std::bind的基本使用格式如下:
#include <functional> // 基本语法 auto new_callable = std::bind(可调用对象, 参数1, 参数2, ...);
其中可调用对象可以是普通函数、成员函数、函数对象、lambda表达式等,后面的参数是要绑定的参数,参数可以是具体的值,也可以是std::placeholders命名空间下的占位符,占位符的格式是_1、_2、_3等,数字代表新可调用对象的第几个参数。
绑定普通函数参数实例
首先看绑定普通函数的场景,假设我们有一个普通的加法函数:
#include <iostream>
#include <functional>
// 普通加法函数
int add(int a, int b) {
return a + b;
}
int main() {
// 绑定add函数的第一个参数为10,第二个参数用占位符_1表示后续传入
auto add_ten = std::bind(add, 10, std::placeholders::_1);
// 调用add_ten时只需要传入第二个参数
std::cout << add_ten(5) << std::endl; // 输出15,等价于add(10,5)
// 绑定两个参数都固定
auto add_fixed = std::bind(add, 3, 4);
std::cout << add_fixed() << std::endl; // 输出7,等价于add(3,4)
// 调整参数顺序,把原函数的第一个参数和第二个参数顺序调换
auto add_swap = std::bind(add, std::placeholders::_2, std::placeholders::_1);
std::cout << add_swap(2, 8) << std::endl; // 输出10,等价于add(8,2)
return 0;
}
绑定成员函数参数实例
绑定类的成员函数时,需要注意第一个参数必须是该类的对象或者对象指针,因为成员函数调用需要依赖对象实例:
#include <iostream>
#include <functional>
class Calculator {
public:
// 成员函数,计算两个数的乘积
int multiply(int a, int b) {
return a * b;
}
};
int main() {
Calculator calc;
// 绑定成员函数,第一个参数是对象实例,后面是成员函数的参数
// 这里绑定calc对象的multiply函数,固定第一个参数为3,第二个参数用占位符
auto mul_three = std::bind(&Calculator::multiply, calc, 3, std::placeholders::_1);
std::cout << mul_three(4) << std::endl; // 输出12,等价于calc.multiply(3,4)
// 也可以用对象指针绑定
Calculator* calc_ptr = &calc;
auto mul_four = std::bind(&Calculator::multiply, calc_ptr, std::placeholders::_1, 4);
std::cout << mul_four(5) << std::endl; // 输出20,等价于calc_ptr->multiply(5,4)
return 0;
}
绑定函数对象实例
函数对象也就是重载了operator()的类实例,同样可以用std::bind绑定参数:
#include <iostream>
#include <functional>
// 函数对象,实现减法
struct Subtractor {
int operator()(int a, int b) {
return a - b;
}
};
int main() {
Subtractor sub;
// 绑定函数对象的第一个参数为10,第二个参数用占位符
auto sub_from_ten = std::bind(sub, 10, std::placeholders::_1);
std::cout << sub_from_ten(3) << std::endl; // 输出7,等价于sub(10,3)
return 0;
}
使用std::bind的注意事项
- 占位符的数字要和后续调用新可调用对象时传入的参数位置对应,_1代表新对象的第一个参数,_2代表第二个,以此类推。
- 绑定对象参数时,默认是值传递,如果希望传递引用,需要使用std::ref或者std::cref包装参数,比如std::bind(func, std::ref(obj), _1)。
- 绑定成员函数时,必须正确获取成员函数的地址,格式是&类名::成员函数名,不能漏掉取地址符。
- std::bind生成的可调用对象的参数个数由占位符的数量决定,调用时传入的参数数量需要和占位符数量匹配。
std::bind与lambda的对比
在C++11之后,很多场景下lambda表达式可以替代std::bind实现参数绑定,lambda的语法更直观,可读性更好。比如上面的add_ten用lambda实现可以写成:
auto add_ten = [](int b) { return add(10, b); };
如果是简单的参数绑定场景,优先选择lambda表达式,如果是需要兼容旧代码或者绑定逻辑比较复杂的情况,再考虑使用std::bind。
std::bindC++函数绑定placeholders函数对象参数绑定修改时间:2026-07-18 18:42:27