1 std::bind

template <class Fn, class... Args> /* unspecified */ bind (Fn&& fn, Args&&... args);

template <class Ret, class Fn, class... Args> /* unspecified */ bind (Fn&& fn, Args&&... args);

1.1 函数模板说明

  • 基于参数f返回一个函数对象,并且以args参数绑定为函数对象的参数。
  • 每个参数要么绑定一个参数值,要么绑定为一个std::placeholders。
  • 如果参数绑定成一个值,那么返回的函数对象将总使用绑定的参数值做为调用参数,即调用传入参数将不起作用;如果参数绑定为std::placeholders,那么返回的函数对象在被调用时需要传入实时参数,参数填充的位置即由placeholder指定的序号。

1.2 函数模板参数说明

  • f : 可调用的函数对象,比如函数对象、函数指针、函数引用、成员函数或者数据成员函数
  • args - 需要绑定的函数的参数列表,使用命名空间占位符std::placeholders::_1,std::placeholders::_2标志参数,其中std::placeholders::_1标志为参数列表中的第一个参数,std::placeholders::_2标志参数列表中的第二个参数,std::placeholders::_3标志参数列表中的第三个参数,以此类推。

1.3 函数模板返回值说明

返回一个函数对象,该函数在调用时使用参数列表args来调用f。如果f是指向类的成员函数,则返回函数第一个参数应该是该类的成员、或者成员对象的引用、或者是成员对象的指针。

2 std::bind可绑定的几种函数形式总结

2.1 绑定普通函数或者静态函数

2.1.1 非模板类型

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;
using namespace std::placeholders;

void StaticBindFunc(int a, int b)
{
        std::cout << "静态函数被调用,a =" << a << ",b=" << b << std::endl;
}

int main()
{
        // 1 使用占位符先占位,然后执行时再传参
        auto staticFunc1 =  std::bind(&StaticBindFunc, std::placeholders::_1, std::placeholders::_2);
        staticFunc1(1,2);

        // 2 使用一个占位符先占位,然后执行时传一个参
        auto staticFunc2 = std::bind(&StaticBindFunc, std::placeholders::_1, 4);
        staticFunc2(3);
        auto staticFunc3 = std::bind(&StaticBindFunc, 5, std::placeholders::_1);
        staticFunc3(6);

        // 3 使用占位符先占位,但是参数位置调换
        auto staticFunc4 = std::bind(&StaticBindFunc, std::placeholders::_2, std::placeholders::_1);
        staticFunc4(7,8);

        getchar();
        return 0;
}

2.1.2 模板类型

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;
using namespace std::placeholders;

template <class T>
void StaticBindFunc(T a, T b)
{
        std::cout << "静态函数被调用,a =" << a << ",b=" << b << std::endl;
}

int main()
{
        // 1 使用占位符先占位,然后执行时再传参
        auto staticFunc1 = std::bind(&StaticBindFunc<int>, std::placeholders::_1, std::placeholders::_2);
        staticFunc1(1, 2);

        // 2 使用一个占位符先占位,然后执行时传一个参
        auto staticFunc2 = std::bind(&StaticBindFunc<int>, std::placeholders::_1, 4);
        staticFunc2(3);
        auto staticFunc3 = std::bind(&StaticBindFunc<int>, 5, std::placeholders::_1);
        staticFunc3(6);

        // 3 使用占位符先占位,但是参数位置调换
        auto staticFunc4 = std::bind(&StaticBindFunc<int>, std::placeholders::_2, std::placeholders::_1);
        staticFunc4(7, 8);

        getchar();
        return 0;
}

2.2 绑定类的成员函数

2.2.1 非模板类型

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;

class A
{
public:
        typedef std::shared_ptr<A> ptr;
        A()
        {
        };
        virtual~A()
        {

        };

public:
        void Add(int a, int b)
        {
                std::cout << "类的成员函数被调用,a =" << a << ",b=" << b << std::endl;
        }
};


int main()
{
        // 1 类的对象
        A tempA;
        auto memberFunc1 = std::bind(&A::Add, tempA, std::placeholders::_1, std::placeholders::_2);
        memberFunc1(1, 2);

        // 2 类的对象的引用
        auto memberFunc2 = std::bind(&A::Add, &tempA, std::placeholders::_1, std::placeholders::_2);
        memberFunc2(3, 4);

        // 3 类的对象的指针
        A* pTempA = new A();

        auto memberFunc3 = std::bind(&A::Add, pTempA, std::placeholders::_1, std::placeholders::_2);
        memberFunc3(5, 6);

        delete pTempA;

        // 4 类的对象的智能指针
        A::ptr pTempAPtr = std::make_shared<A>();
        auto memberFunc4 = std::bind(&A::Add, pTempAPtr, std::placeholders::_1, std::placeholders::_2);
        memberFunc4(7, 8);

        getchar();
        return 0;
}

2.2.2 模板类型

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;

class A
{
public:
        typedef std::shared_ptr<A> ptr;
        A()
        {
        };
        virtual~A()
        {

        };

public:
        template <class T>
        void Add(T a, T b)
        {
                std::cout << "类的成员函数被调用,a =" << a << ",b=" << b << std::endl;
        }
};


int main()
{
        // 1 类的对象
        A tempA;
        auto memberFunc1 = std::bind(&A::Add<int>, tempA, std::placeholders::_1, std::placeholders::_2);
        memberFunc1(1, 2);

        // 2 类的对象的引用
        auto memberFunc2 = std::bind(&A::Add<int>, &tempA, std::placeholders::_1, std::placeholders::_2);
        memberFunc2(3, 4);

        // 3 类的对象的指针
        A* pTempA = new A();

        auto memberFunc3 = std::bind(&A::Add<int>, pTempA, std::placeholders::_1, std::placeholders::_2);
        memberFunc3(5, 6);

        delete pTempA;

        // 4 类的对象的智能指针
        A::ptr pTempAPtr = std::make_shared<A>();
        auto memberFunc4 = std::bind(&A::Add<int>, pTempAPtr, std::placeholders::_1, std::placeholders::_2);
        memberFunc4(7, 8);

        getchar();
        return 0;
}

2.3 绑定类的公有成员变量

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;

class A
{
public:
        typedef std::shared_ptr<A> ptr;
        A()
        {
        };
        virtual~A()
        {

        };

public:
        int m_Value = 20;
};


int main()
{
        // 绑定类公共成员变量,不可绑定私有成员变量
        auto memberVar = std::bind(&A::m_Value, std::placeholders::_1);

        // 1 类对象做参数传递
        A tempA;

        std::cout << memberVar(tempA) <<std::endl;

        // 2 类对象引用做参数传递
        std::cout << memberVar(&tempA) << std::endl;

        // 3 类指针做参数传递
        A* pTempA = new A();
        std::cout << memberVar(pTempA) << std::endl;
        delete pTempA;

        // 4 类智能指针做参数传递
        A::ptr pTempAPtr = std::make_shared<A>();

        std::cout << memberVar(pTempAPtr) << std::endl;

        std::cout << memberVar(std::make_shared<A>()) << std::endl;

        getchar();
        return 0;
}

2.4 绑定lambda表达式

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;


int main()
{
        // 1 lambda表达式
        auto memberFunc1 = std::bind([](int a, int b) { std::cout << "lambda函数被调用,a =" << a << ",b=" << b << std::endl; }, std::placeholders::_1, std::placeholders::_2);
        memberFunc1(1, 2);


        getchar();
        return 0;
}