bind
昨天有粉丝问我,bind1st和bind有啥区别?今天就来简单讲讲。
 
 bind1st和bind2nd在STL中主要用于二元函数对象,将其中的一元绑定成一个固定的量,成为一元函数变量。
 在C++11标准中,这两位因为不够灵活,所以已经被bind所取代。
 
 bind起源于非标准boost库,在c++11标准中正式纳入标准库,其更加灵活,最多可以绑定20个函数对象的参数。
bind的用法
先随便整上点函数:
void hello(string str) { cout << str << endl; }
int sum(int a, int b) { return a + b; }
class Test
{
public:
	int sum(int a, int b) { return a + b; }
};
  然后再来看bind的实际应用:
int main()
{
	// bind是函数模板 可以自动推演模板类型参数
	bind(hello, "hello bind!")()//result:print:hello bind!
	cout << bind(sum, 10, 20)() << endl;//result:print:30
	cout << bind(&Test::sum, Test(), 20, 30)() << endl;//result:print:50
	// 参数占位符 绑定器出了语句,无法继续使用
	bind(hello, _1)("hello bind 2!");
	cout << bind(sum, _1, _2)(200, 300) << endl;//result:print:500
	return 0;
}
  在语句bind(hello, "hello bind!")();中,bind将“hello bind!”绑定至hello的string类型参数,并返回一个函数对象,调用这个函数对象的operator()函数,完成打印字符串的过程。
在语句bind(hello, _1)("hello bind 2!");中的_1是名称空间 placeholders中的,用法placeholder::_1。
 此为参数占位符,代表hello的第一个参数等待用户输入。在本例中将参数“hello bind 2!”传递给operator()函数完成调用。
用function实现对bind绑定的函数对象的类型保留
bind有个缺点,不知道大家发现了没有。
 bind无法保存它所绑定过的函数对象!
所以就需要function和它进行配合。
 
int main()
{
	function<void(string)> func1 = bind(hello, _1);
	func1("hello china!");
	func1("hello shan xi!");
	func1("hello si chuan!");
	return 0;
}
  bind 和function实现线程池(假)
先把线程类定义好:
// 线程类
class Thread
{
public:
	Thread(function<void(int)> func, int no) :_func(func), _no(no) {}
	//这里需要包含头文件#include<thread>
	thread start()
	{
		//定义线程t执行func函数
		thread t(_func, _no); // _func(_no)
		return t;
	}
private:
	function<void(int)> _func;//接收绑定器返回的函数对象
	int _no;//线程编号
};
  再定义好线程池类:
// 线程池类
class ThreadPool
{
public:
	ThreadPool() {}
	~ThreadPool()
	{
		// 这里是指针,所以不能依靠vector析构自动析构,得手动释放Thread对象占用的堆资源
		for (int i = 0; i < _pool.size(); ++i)
		{
			delete _pool[i];
		}
	}
	// 开启线程池
	void startPool(int size)
	{
		for (int i = 0; i < size; ++i)
		{
			_pool.push_back(
				new Thread(bind(&ThreadPool::runInThread, this, _1), i));
		}
		//执行线程函数
		for (int i = 0; i < size; ++i)
		{
			_handler.push_back(_pool[i]->start());
		}
		for (thread &t : _handler)
		{
			//等待线程执行完毕
			t.join();
		}
	}
private:
	vector<Thread*> _pool;
	vector<thread> _handler;
	// 把runInThread这个成员方法充当线程函数 thread pthread_create
	void runInThread(int id)
	{
		cout << "call runInThread! id:" << id << endl;
	}
};
  应用:
int main()
{
	ThreadPool pool;
	pool.startPool(10);//创建10个线程
	return 0;
}
#endif
  这里只是个概念模型,用还是用不了的。
 
参考文献
[1] 施磊.腾讯课堂——C++高级.图论科技,2020.7.

京公网安备 11010502036488号