bind适配器

 std::bind模板函数是一个通用的函数适配器,是用一个可调用对象及其参数,生成一个新的可调用对象,以适应模板。

#include <iostream>
#include <string>
#include <functional>

using namespace std;



//普通函数
void show(int a, const string& str)
{
	std::cout << a << str << std::endl;
}

class AA
{
public:
	static void show(int a, const string& str)
	{
		std::cout << a << str << std::endl;
	}
	void operator()(int a, const string& str)
	{
		std::cout << a << str << std::endl;
	}
	void show1(int a, const string& str)
	{
		std::cout << a << str << std::endl;
	}
};

int main()
{
	//包装器包装普通成员函数
	void(*fp)(int, const string&) = show;
	std::function<void(int, const string&)> fn1 = show;
	std::function<void(int, const string&)> fn11 = bind(show, placeholders::_1, placeholders::_2);
	std::function<void(const string&)> fn111 = bind(show, 2, placeholders::_1);
	std::function<void(int, const string&, int)> fn1111 = bind(show, placeholders::_1, placeholders::_2);
	fn1(1, "你好");
	fn11(1111, "你好");
	fn111("你好"); fn1111(1111111,"你好",90);

	//包装类的静态成员变量
	std::function<void(int, const string&)> fn2 = AA::show;
	std::function<void(int, const string&)> fn22 = bind(AA::show, placeholders::_1, placeholders::_2);
	fn2(2, "你好");
	fn22(2, "你好");

	//包装仿函数
	AA aa;
	std::function<void(int, const string&)> fn3 = aa;
	std::function<void(int, const string&)> fn33 = bind(aa, placeholders::_1, placeholders::_2);
	fn3(3, "你好");
	fn33(3, "你好");

	//包装lambda函数	
	std::function<void(int, const string&)> fn5 = [](int a, const string& str) {
		std::cout << a << str << std::endl;
	};
	std::function<void(int, const string&)> fn55 = bind([](int a, const string& str) {
		std::cout << a << str << std::endl;
		}, placeholders::_1, placeholders::_2);
	fn5(4, "你好");
	fn55(4, "你好");

	//包装类的非静态成员函数
	AA a;
	std::function<void(AA&, int, const string&)> fn6 = &AA::show1;
	std::function<void(int, const string&)> fn66 = bind(&AA::show1, &a, placeholders::_1, placeholders::_2);
	fn6(a, 5, "你好");
	fn66(55555555, "你好");

	std::function<void(int, const string&)> fn7;
	try
	{
		fn7(1, "");
	}
	catch (std::bad_function_call except)
	{
		std::cout << "functionName;" << __func__ << ",Line:" << __LINE__ << except.what() << endl;
	}


	return 0;
}

应用场景一:可变函数与参数

#include <iostream>
#include <string>
#include <functional>

using namespace std;


//普通函数
void show(int a, const string& str)
{
	std::cout << a << str << std::endl;
}
void show0(int a)
{
	std::cout << a << std::endl;
}

class AA
{
public:
	void show1(int a, const string& str)
	{
		std::cout << a << str << std::endl;
	}
};

template<typename Fn, typename ...Args>
auto show3(Fn&& fn, Args&&...args)
{
	cout << "************\n";
	auto f = bind(forward<Fn>(fn), forward<Args>(args)...);//args...作为整体传递
	f();
	cout << "************\n";
	return f;
}
//可变参数
int main()
{
	show3(show, 1, "dfdfd");
	show3(show0, 89);
	AA a;
	show3(&AA::show1, &a, 89, "hello");
	return 0;
}

 应用场景二:回调函数的实现

        在消息队列和网络库的框架中,当接收到消息(报文)时,回调用户自定义的函数对象,把消息(报文)参数传给它,由它决定如何处理。

#include <iostream>
#include <string>
#include <thread>                      // 线程类头文件。
#include <mutex>                      // 互斥锁类的头文件。
#include <deque>                      // deque容器的头文件。
#include <queue>                      // queue容器的头文件。
#include <condition_variable>       // 条件变量的头文件。
#include <functional>

using namespace std;

void show(const string& message) {  // 处理业务的普通函数
    cout << "处理数据:" << message << endl;
}

class FrameWork
{
public:
    FrameWork(const string& message)
        :m_str(message)
    {}
    void dowork(const string& message)
    {
        // 处理出队的数据(把数据消费掉)。
        std::cout << "这是回调函数处理的代码,业务层.\t" 
            << message
            << "\t"
            << m_str\
            << std::endl;
    }

private:
    string m_str;
};

class Bussiness
{
    function<void(const string&)> m_callback;  // 回调函数对象。
public:
    // 注册回调函数,回调函数只有一个参数(消费者接收到的数据)。
    template<typename Fn, typename ...Args>
    void callback(Fn&& fn, Args&&...args) {
        m_callback = bind(forward<Fn>(fn), forward<Args>(args)..., std::placeholders::_1);  // 绑定回调函数。
    }

    void dowork(const string& message)
    {         
        std::cout << "***********框架层开始处理代码*************\n";
        // 处理出队的数据(把数据消费掉)。
        if (m_callback) m_callback(message);  // 回调函数,把收到的数据传给它。
        std::cout << "************框架层结束处理代码************\n";
    }
};

int main()
{
    Bussiness aa;
    FrameWork b("hello, it's me");
    aa.callback(&FrameWork::dowork, &b);    // 把类成员函数BB::show()注册为回调函数。
    aa.dowork("mesage");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值