C++ bind的用法

bind是标准库函数,定义在头文件functional中,可以将bind函数看作一个通用函数适配器,它接受一个可调用对象,生成一个新的可调用对象来适应元对象的参数列表。

auto newCallable = bind(originCallable, arg_list);

newCallable会调用originCallable,并传递给它arg_list中的参数。arg_list中含有_1或者_2这样的占位符,使用名字空间std:placeholders_n代表newCallable接收到的从外部传来的第n个参数。
例子:

#include <iostream>
#include <fstream>
#Include <string>
#include <vector>
#include <algorithm>

using namespace std;
using namespace std::placeholders;

bool size_check(const string &s, size_t sz) {
	return s.size() > sz;
}

int main(int argc, char **argv) {
	ifstream f("test");
	if (f) {
		vector<string> v;
		string tmp;
		while (f >> tmp) {
			v.push_back(tmp);
		}
		size_t sz = 6;
		int cnt = count_if(v.begin(), v.end(), bind(size_check, _1, sz)); //_1为vector中的string,sz的6传递给了size_check的第二个参数
		cout << "String longer than 6 number is " << cnt << endl;
	} else {
		eixt(1);
	}
	return 0;
}

例2

#include <iostream>
#include <fstream>
#Include <string>
#include <vector>
#include <algorithm>

using namespace std;
using namespace std::placeholders;

bool size_check(const string &s, size_t sz) {
	return s.size() <= sz;
}

int main(int argc, char **argv) {
	vector<int> v = {1,2,3,4,5,6,7,8,9};
	string target;
	cout << “Enter the target " << endl;
	cin >> target;
	auto itr = find_if(v.begin(), v.end(), bind(size_check, target, _1)); //_1是vector中的每个int值,找出string长度
	cout << "The first number that longer than target is " << *itr << endl;

	return 0;
}
<think>我们正在讨论C++中的`std::bind`,需要结合用户之前的问题(关于`std::function`)和当前需求(`std::bind`的使用详解)来组织答案。 注意:用户提供的引用[1]和[2]是关于`std::bind`的,我们需要整合这些信息并扩展。 回答结构: 1. 概述`std::bind`是什么,作用是什么,与`std::function`的关系。 2. 基本语法和使用方法,包括绑定普通函数、成员函数、lambda表达式等。 3. 占位符(placeholders)的使用。 4. 参数传递方式(拷贝还是引用)以及如何使用`std::ref`和`std::cref`传递引用。 5. 使用示例代码。 6. 注意事项和常见问题。 7. 生成相关问题。 注意:使用中文,代码示例用C++,并按照要求处理数学公式(但本主题可能较少涉及数学公式,若有则按规则处理)。 引用标注:在适当的地方标注引用[^1]和[^2](用户提供的两个引用)。 由于用户之前的问题是关于`std::function`的,我们可以在适当的地方提及两者的协同工作(如引用[1]提到bind返回的是function对象)。 </think>### C++ 中 `std::bind` 使用详解 `std::bind` 是 C++11 引入的函数适配器,用于创建新的可调用对象(`std::function`)。它通过**部分参数绑定**和**参数重排序**机制,将现有函数适配成新函数签名,常用于回调系统、事件处理等场景[^1]。 #### 1. 核心功能与原理 - **参数绑定**:将特定值固定为函数参数 ```cpp auto newFunc = std::bind(originalFunc, arg1, arg2); ``` - **占位符重排**:使用 `_1, _2...` 调整参数顺序 ```cpp namespace ph = std::placeholders; auto reversed = std::bind(func, ph::_2, ph::_1); // 参数顺序反转 ``` - **返回值类型**:生成 `std::function` 对象,支持类型擦除[^1] #### 2. 基础用法示例 ##### 绑定普通函数 ```cpp #include <functional> using namespace std::placeholders; // 引入 _1, _2... // 原函数 void print(int a, std::string b, double c) { std::cout << a << ", " << b << ", " << c; } int main() { // 固定部分参数 auto f1 = std::bind(print, 10, _1, 3.14); f1("Hello"); // 输出: 10, Hello, 3.14 // 重排序参数 auto f2 = std::bind(print, _3, _1, _2); f2("World", 2.718, 20); // 输出: 20, World, 2.718 } ``` ##### 绑定成员函数 ```cpp class Widget { public: void update(int value, const std::string& msg) { std::cout << value << " | " << msg; } }; int main() { Widget w; // 绑定对象实例(需用指针) auto memberFunc = std::bind(&Widget::update, &w, _1, _2); memberFunc(99, "Bound"); // 输出: 99 | Bound } ``` #### 3. 参数传递机制 | **传递方式** | 语法 | 特点 | |--------------|---------------------------|-----------------------| | 值传递(默认) | `std::bind(func, arg)` | 创建参数拷贝 | | 引用传递 | `std::bind(func, std::ref(arg))` | 避免拷贝,修改影响原值[^2] | | 常量引用 | `std::bind(func, std::cref(arg))` | 只读访问 | **引用传递示例**: ```cpp void modify(int& x) { x *= 2; } int main() { int value = 5; // 错误:默认值传递无法修改原值 // auto wrong = std::bind(modify, value); // 正确:使用std::ref auto correct = std::bind(modify, std::ref(value)); correct(); std::cout << value; // 输出: 10 } ``` #### 4. 结合 Lambda 的高级用法 `std::bind` 可嵌套 Lambda 实现复杂逻辑: ```cpp // 创建带预设条件的比较器 auto greaterThan = [](int threshold) { return std::bind(std::greater<int>(), _1, threshold); }; std::vector<int> v = {5, 3, 8, 1}; auto it = std::find_if(v.begin(), v.end(), greaterThan(4)); // 找到第一个 >4 的元素: 5 ``` #### 5. 注意事项 1. **生命周期管理**: ```cpp // 危险:临时对象销毁导致悬空引用 auto danger = std::bind(&Widget::update, std::make_unique<Widget>().get(), _1, _2); ``` 2. **性能开销**: - 每次调用有额外跳转(≈2-10ns) - 优先选用 Lambda(性能更高且类型安全) 3. **占位符限制**: - `_1` 到 `_29` 在 `<functional>` 中定义 - 超出范围需自定义: ```cpp struct Placeholders { static decltype(_1) _30; }; ``` 4. **重载函数歧义**: ```cpp void func(int); void func(double); // 需显式指定类型 auto f = std::bind(static_cast<void(*)(int)>(func), _1); ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值