【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接收,避免手动写类型;
相关推荐
小宇子2B3 天前
一个 Vec 的数据到底在内存哪:栈、堆,和它们相向而行的真相
后端·编程语言
alwaysrun3 天前
C++之类型安全格式化format
c++·程序员·编程语言
大熊猫侯佩6 天前
WWDC26前瞻:Swift 即将迎来的那些新内置类型
swift·编程语言·wwdc
iiiiyu7 天前
IO流(二)
java·开发语言·数据结构·编程语言
触底反弹7 天前
苹果换芯片,用户说「真香」;微软换芯片,用户说「退货」—— 同样的事,为什么结果完全相反?
java·架构·编程语言
gis分享者7 天前
学习threejs,实现炫酷的3D编程语言地球可视化效果
可视化·编程语言·threejs·地球·spheregeometry·raycaster·meshbasic
Rust研习社8 天前
90% 的 Rust 新手都不知道的 3 个实用开发技巧
后端·rust·编程语言
传说之后8 天前
Go语言入门:从零到Hello World
后端·编程语言