C++11-std::bind

std::bind介绍

std::bind用于给函数绑定预设的参数, 这样实际上也可以给函数带上状态, 起到类似闭包的效果

以下是bind的几种用法

std::bind普通函数

看示例代码, 这里使用 std::placeholders::_1, 表达的是第一个参数的占位符

第2个参数预设为100, 这样产生的新bind结果函数 add_100

他的类型为一个新函数-- 返回值int, 同时带有1个int型入参

如代码中的 std::function<int(int)>的声明

#include <iostream>
#include <functional>
#include <string>
using namespace std;

int sum(int a, int b)
{
    return a+b;
}


int main(int argc, char* argv[])
{
    std::function<int(int)> add_100 = std::bind(sum, std::placeholders::_1, 100);
    cout << add_100(10) << endl;

    return 0;
}

运行结果

std::bind仿函数

#include <iostream>
#include <functional>
using namespace std;


class Comparator
{
public:
    bool operator () (int a, int b)
    {
        return a < b;
    }
};

int main(int argc, char* argv[])
{
    Comparator comparator;
    auto lt_100 = std::bind(comparator, std::placeholders::_1, 100);
    cout << "101 lt_100: " << lt_100(101) << endl;

    return 0;
}

运行结果

 std::bind类成员函数

以下为使用std::bind类成员函数示例代码, 写法如:

std::bind(类名::成员函数, 类对象指针, ...其他参数...)

#include <iostream>
#include <functional>
#include <string>
using namespace std;

class Speaker
{
public:
    void Speak()
    {
        cout<<"My name is "<<name<<endl;
    }
    string name;
};

int main(int argc, char* argv[])
{
    Speaker s;
    s.name = "WangLei";
    
    auto do_speak = std::bind(Speaker::Speak, &s);
    do_speak();

    return 0;
}

运行结果: 

 std::bind的实际应用场景

个人很少使用, 从这个bind的能力上讲,应该是可以用在一些简化复杂函数调用的场景下, 比如有一个长参数列表的函数,可能大部分调用其中3个参数总是一致的,那么可以声明一个bind函数来实现这几个一致的调用分支,  如下示例:

int PrintInvoice(string& title, vector<InvoiceItem>& itemList, Page& p, Font& f, Color& c)
{
    ...
}


Page pageA4("A4");
Font f("宋体");
Color b("black");

PrintInvoice("aa", itemList1, pageA4, f, b);
PrintInvoice("bb", itemList2, pageA4, f, b);
PrintInvoice("cc", itemList3, pageA4, f, b);

可以通过使用std::bind把一致的参数收起来

另外在一些需要引入其他参数的作为回调函数场景,比如配合 stable_sort 等情况也可以使用bind方式提供出符合要求的函数, 而不必通过 functor 对象

posted @ 2022-07-15 07:24  飞天赤狐  阅读(190)  评论(0编辑  收藏  举报