当前位置 博文首页 > 藏经阁:C++ bind用法与代码演示

    藏经阁:C++ bind用法与代码演示

    作者:[db:作者] 时间:2021-07-26 08:53

    C++ bind, 有点类似函数指针,但是用法比函数指针更灵活,在绑定的时候可以预设值参数,例如下面的代码:

    #include <iostream>
    #include <functional>
    
    using namespace std::placeholders;
    
    void fn(int n1, int n2, int n3) 
    {
    	std::cout << n1 << " " << n2 << " " << n3 << std::endl;
    }
    
    int fn2() 
    {
    	std::cout << "fn2 has called.\n";
    	return -1;
    }
    
    int main()
    {
    	auto bind_test1 = std::bind(fn, 1, 2, 3);
    
    	//用占位符填充参数,占位符从 _1开始,没有_0
    	auto bind_test2 = std::bind(fn, _1, _2, _3);
    	auto bind_test3 = std::bind(fn, 0, _1, _2);
    	auto bind_test4 = std::bind(fn, _2, 0, _1);
    
    	bind_test1();  //输出1 2 3
    
    	bind_test2(3, 8, 24);  //输出3 8 24
    	bind_test2(1, 2, 3, 4, 5); //输出1 2 3,4和5会被丢弃
    
    	bind_test3(10, 24);  //输出0 10 24
    	bind_test3(10, fn2());  //输出0 10 -1
    	bind_test3(10, 24, fn2());  //输出0 10 24,fn2会被调用,但其返回值会被丢弃
    
    	bind_test4(10, 24);//输出24 0 10
    
    	return 0;
    }
    
    

    输出结果:
    1 2 3
    3 8 24
    1 2 3
    0 10 24
    fn2 has called.
    0 10 -1
    fn2 has called.
    0 10 24
    24 0 10

    上面在绑定时都是设置的为全局函数,那么是否可以设为类成员函数呢,当然可以,看下面的代码

    #include <iostream>
    #include <functional>
    
    using namespace std::placeholders;
    using namespace std;
    
    class Test
    {
    public:
    
    	int fun1(int a, int b)
    	{
    		return a * b;
    	}
    
    	static void fun2(int a, int b)
    	{
    		cout << "a-b = " << a - b << endl;
    	}
    };
    
    int main()
    {
    	Test t;
    	auto f1 = std::bind(&Test::fun1, t, 10, _1);  //如果在类里面调用那么就填this
    
    	cout << f1(3) << endl;
    
    	auto f2 = std::bind(&Test::fun2, 3, 9);
    	f2();
    
    	return 0;
    }
    

    在绑定类成员函数时,如果是非静态的,则需要传对象,类里面绑定则传this;绑定静态成员函数,不用传对象。

    bind有什么用呢,主要还是用在回调函数的注册。例如下面的写法

    A.h
    using cb_data_capture = std::function<void(int)>;
    
    class A
    {
    public:
    	void register_cb(cb_data_capture cb)
    	{
    		m_cb = cb;
    	}
    	
    private:
    	cb_data_capture m_cb;
    };
    
    ———————————————————————————————————————————————————————————————
    
    B.h
    class B
    {
    public:
        void Init()
        {
        	m_pA->register_cb(&B::fun,  this, _1);
        }
        
    public:
    	void fun(int a);
    	
    private:
    	A*  m_pA;
    };
    

    A的回调在类B中赋值, A的某些地方又会用到回调,那么此时的bind就起作用了。

    cs
    下一篇:没有了