c++的bind使用方法

c++的bind使用方法

除了容器有适配器之外,其实函数也提供了适配器,适配器的特点就是将一个类型改装成为拥有子集功能的新的类型。其中函数的适配器典型的就是通过std::bind来实现。

std::bind函数定义在头文件functional中,是一个函数模板,它就像一个函数适配器,接受一个可调用对象(callable object),生成一个新的可调用对象来“适应”原对象的参数列表。一般而言,我们用它可以把一个原本接收N个参数的函数fn,通过绑定一些参数,返回一个接收M个(M可以大于N,但这么做没什么意义)参数的新函数。同时,使用std::bind函数还可以实现参数顺序调整等操作。

可调用 (Callable) 中描述,调用指向非静态成员函数指针或指向非静态数据成员指针时,首参数必须是引用或指针(可以包含智能指针,如 std::shared_ptrstd::unique_ptr),指向将访问其成员的对象。

官方示例

#include <random>
#include <iostream>
#include <memory>
#include <functional>
 
void f(int n1, int n2, int n3, const int& n4, int n5)
{
    std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '\n';
}
 
int g(int n1)
{
    return n1;
}
 
struct Foo {
    void print_sum(int n1, int n2)
    {
        std::cout << n1+n2 << '\n';
    }
    int data = 10;
};
 
int main()
{
    using namespace std::placeholders;  // 对于 _1, _2, _3...
 
    // 演示参数重排序和按引用传递
    int n = 7;
    // ( _1 与 _2 来自 std::placeholders ,并表示将来会传递给 f1 的参数)
    auto f1 = std::bind(f, _2, 42, _1, std::cref(n), n);
    n = 10;
    f1(1, 2, 1001); // 1 为 _1 所绑定, 2 为 _2 所绑定,不使用 1001
                    // 进行到 f(2, 42, 1, n, 7) 的调用
 
    // 嵌套 bind 子表达式共享占位符
    auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5);
    f2(10, 11, 12); // 进行到 f(12, g(12), 12, 4, 5); 的调用
 
    // 常见使用情况:以分布绑定 RNG
    std::default_random_engine e;
    std::uniform_int_distribution<> d(0, 10);
    std::function<int()> rnd = std::bind(d, e); // e 的一个副本存储于 rnd
    for(int n=0; n<10; ++n)
        std::cout << rnd() << ' ';
    std::cout << '\n';
 
    // 绑定指向成员函数指针
    Foo foo;
    auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
    f3(5);
 
    // 绑定指向数据成员指针
    auto f4 = std::bind(&Foo::data, _1);
    std::cout << f4(foo) << '\n';
 
    // 智能指针亦能用于调用被引用对象的成员
    std::cout << f4(std::make_shared<Foo>(foo)) << '\n'
              << f4(std::make_unique<Foo>(foo)) << '\n';
}

输出:

2 42 1 10 7
12 12 12 4 5
1 5 0 2 0 8 2 2 10 8
100
10
10
10

更多编程资料见公众号 xutopia77

在wxWidgets中,可以使用`Bind()`方法来将事件处理函数与特定的控件事件关联起来。例如,下面是一个示例代码片段,将一个按钮的`wxCommandEvent`事件与一个事件处理函数关联起来: ```c++ class MyFrame : public wxFrame { public: MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size); private: void OnButtonClicked(wxCommandEvent& event); wxButton* m_button; }; MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, wxID_ANY, title, pos, size) { m_button = new wxButton(this, wxID_ANY, "Click me", wxPoint(10, 10), wxSize(100, 30)); Bind(wxEVT_BUTTON, &MyFrame::OnButtonClicked, this, m_button->GetId()); } void MyFrame::OnButtonClicked(wxCommandEvent& event) { wxMessageBox("Button clicked!"); } ``` 在上面的代码中,我们在`MyFrame`类的构造函数中创建了一个按钮,并将其与窗口关联起来。然后,我们调用`Bind()`方法,将按钮的`wxEVT_BUTTON`事件与`OnButtonClicked()`方法关联起来。`Bind()`方法的参数包括事件类型、事件处理函数、事件处理函数所在的对象以及控件的ID。 当用户单击按钮时,将会触发`wxEVT_BUTTON`事件,事件处理函数`OnButtonClicked()`将被调用,并显示一个消息框。 除了按钮事件之外,wxWidgets还支持许多其他类型的事件,包括鼠标事件、键盘事件、菜单事件等。您可以使用`Bind()`方法将任何类型的事件与事件处理函数关联起来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值