【C++ STL】bind适配器详解

std::bind适配器的详解

std::bind 是 C++11 引入的函数适配器,位于头文件 <functional> 中。它可以将可调用对象(函数、函数指针、成员函数、函数对象等)与其部分参数绑定,生成一个新的可调用对象,这个新对象可以存储并在后续调用。它是传统 bind1st/bind2nd 的现代替代品,功能更强大且使用更灵活。

  • 基本语法
    • 可调用对象:可以是普通函数、函数指针、成员函数指针、函数对象(仿函数)等。
    • 参数 :可以指定具体的值,也可以用占位符(std::placeholders::_1, _2, ...)表示"将来调用时提供的参数"。
    • 返回一个新的可调用对象,其类型为 std::bind 返回的未指定类型(通常用 autostd::function 保存)。
    • 占位符 定义在 std::placeholders 命名空间中,_1 代表调用新对象时的第一个实参,_2 代表第二个,依此类推。
c++ 复制代码
#include <functional>
auto bound_func = std::bind(可调用对象, 参数1, 参数2, ..., 参数N);

!注意 占位符的数量,必须等于"新函数对象需要接收的参数个数",否则会编译错误。

绑定普通函数

c++ 复制代码
using namespace std::placeholders;

// 1、绑定所有参数,生成一个无参可调用对象
auto bound_fun1 = bind(add, 100, 200);

int res = bound_fun1();		// 100 + 200 = 300

// 2、绑定部分参数
// // 第一个参数由调用时提供,第二个固定为100
auto bound_fun2 = bind(add, _1, 100);
res = bound_fun2(200);		// 200 + 100 = 300

// 交换参数顺序
auto bond_fun3 = bind(add, _2, _1);
bond_fun3(100, 200);	// 200 + 100 = 300

绑定仿函数

c++ 复制代码
template<typename T>
struct Multiply {
	T operator()(T a, T b) {
		return a * b;
	}
};

int main()
{
	using namespace std::placeholders;

	vector<int> v = { 1, 2, 3, 4 };
	
	// 两种绑定方式都可以
	// Multiply<int> mult;
	// auto bound_fun = bind(mult, _1, 10);
	auto bound_fun = bind(Multiply<int>(), _1, 10);

	for (int i : v) {
		cout << bound_fun(i) << endl;	// 10 20 30 40
	}

	return EXIT_SUCCESS;
};

绑定类成员函数

绑定类成员函数时,需注意:第一个参数必须是"类对象的地址"(&对象)或"类指针",后续参数为成员函数的参数(固定值/占位符)。

c++ 复制代码
class Person {
public:
	void printName(string name, int age)
	{
		cout << "name = " << name << ",age = " << age << endl;
	}
};

int main()
{
	using namespace std::placeholders;

	Person p;
	// 第一个参数&p是类对象的指针
	auto bound_fun1 = bind(&Person::printName, &p, _1, 25);
	bound_fun1("张三");	// name = 张三,age = 25

	return EXIT_SUCCESS;
};

使用注意事项

  • 必须包含头文件functional,否则会出现编译错误;
  • 占位符的使用:占位符的数量必须与"新函数对象需要接收的参数个数"一致;占位符的序号(_1、_2)必须与新函数调用时的参数顺序对应;
  • 绑定类成员函数的注意点:必须传入类对象的地址(&对象)或类指针,否则无法调用成员函数;绑定const成员函数时,对象地址也需是const类型(若对象是const);
  • bind返回的函数对象类型复杂,建议用auto接收,避免手动写类型;
相关推荐
Quz6 小时前
QML 信号与槽:直接绑定与跨文件通信
qt·编程语言·设计
wenb1n2 天前
MySQL诊断系列(3/6):索引分析——5个SQL揪出“僵尸索引”
数据库·人工智能·编程语言
快乐星空Maker4 天前
C++【生存游戏】开发:荒岛往事 第三期
开发语言·c++·游戏·编程语言
小林ixn4 天前
Python基础全梳理:从注释到函数,这些细节你都掌握了吗?
python·编程语言
甜味弥漫5 天前
一文搞懂 TypeScript:为什么 JavaScript 需要类型?从 JS 到 TS 入门笔记
编程语言
饼干哥哥7 天前
10.5% 深层转化、90%+ 新用户,ChatGPT Ads 值得吗?
算法·正则表达式·编程语言
清秋9 天前
全网最全 ECMAScript 攻略( 更新至 ES2026)
前端·javascript·编程语言
Jack201 个月前
HarmonyOS开发中请求拦截器链:日志、认证、重试
编程语言
Rust研习社1 个月前
组合真的优于继承吗?为什么 Rust 和 Go 都拥抱组合舍弃继承?
后端·rust·编程语言
Jack201 个月前
HarmonyOS开发中RESTful API封装:网络层架构设计
编程语言