整理c++ function和bind的常用用法

c++的function是一种函数包装器,可以保存其他可调用对象,如函数,lambada表达式,bind()表达式,成员函数等。bind可以生成函数的转发调用包装器。bind和function都定义在头文件<functional>里。

参考链接

使用std::function绑定一个自由函数

#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholders

void printValues(int a, int b, int c) {
    std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}


int main() {

    //绑定一个function对象到自由函数,function传入的函数返回值和参数列表需要和实际绑定的函数一样
    std::function<void(int,int,int)>  func = printValues;
    func(100, 200, 300);
    return 0;
}

使用std::function绑定一个lambda表达式

#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholders

int main() {
    //绑定一个lambda表达式
    std::function<void(int,int)>  funcL = [](int a,int b) -> void
    {
        std::cout << "a = " << a << " b = " << b << std::endl;
    };
    funcL(123, 456);
    return 0;
}

使用std::function绑定一个类成员函数,推荐使用std::bind来绑定类的成员函数

#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholders

struct MyFoo
{
    int val;
    MyFoo(int i) : val(i) { std::cout << "MyFoo cons" << i << '\n'; }
    void printVal() const { std::cout << val << '\n'; }
    void printAddVal(int i) { std::cout << val + i << '\n'; }
};

int main() {
    // 存储到成员函数的调用
    //因为成员函数在调用时,会隐式传入this指针,所以绑定时,需要传入一个MyFoo&参数
    //如果成员函数用const修饰,那么要传入const MyFoo&
    std::function<void(const MyFoo&)> my_foo_print = &MyFoo::printVal;
    MyFoo mfoo(27895);
    my_foo_print(mfoo);
    my_foo_print(30001122); //30001122被构造成MyFoo的对象

    std::function<void(MyFoo&, int)> my_foo_printadd = &MyFoo::printAddVal; 
    my_foo_printadd(mfoo,20);
    //my_foo_printadd(46123,20);   //46123会被构造成为一个临时对象,临时对象不能绑定到const引用,编译会报错

    //使用std::bind来绑定,类的成员函数
    MyFoo mfoo2(54321);
    std::function<void(void)> my_foo_print2 = std::bind(&MyFoo::printVal, &mfoo2);
    my_foo_print2();
    std::function<void(int)> my_foo_printadd2 = std::bind(&MyFoo::printAddVal, &mfoo2, std::placeholders::_1);
    my_foo_printadd2(300);
    return 0;
}

使用std::bind,比较常用的就是绑定类成员函数或一个自由函数

#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholders

void printValues(int a, int b, int c) {
    std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}


struct MyFoo
{
    int val;
    MyFoo(int i) : val(i) { std::cout << "MyFoo cons" << i << '\n'; }
    void printVal() const { std::cout << val << '\n'; }
    void printAddVal(int i) { std::cout << val + i << '\n'; }
};


using namespace std::placeholders;

int main()
{
    MyFoo foo(100);

    auto print = std::bind(&MyFoo::printVal, &foo);
    print();

    auto printAdd = std::bind(&MyFoo::printAddVal, &foo, _1);
    printAdd(200); //参数传入200,对应占位符_1

    auto printAdd2 = std::bind(&MyFoo::printAddVal, &foo, 50);
    printAdd2();    //参数固定传入50


    //传给printValues的第一个参数是display的第2个参数,30
    //printvalues的第二个参数是固定值20
    //printvalues的第3个参数是display的第1个参数,10
    auto display = std::bind(printValues, _2, 20, _1);
    display(10, 30);    //a = 10, b = 20, c = 30

    //传给printValues的第一个参数是display2的第3个参数,20
    //printvalues的第二个参数是display2的第一个参数,30
    //printvalues的第3个参数是display的第2个参数,10
    auto display2 = std::bind(printValues, _3, _1, _2);
    display2(30, 10, 20);    //a = 20, b = 30, c = 10
    return 0;
}

使用std::function定义一个函数类型,一般在给其他类提供一个callback类型时使用。

#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholders

void printValues(int a, int b, int c) {
    std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}


typedef std::function<void(int,int,int)> ShowFunc;
using Display = std::function<void(int,int,int)>;


using namespace std::placeholders;


int main()
{
    ShowFunc func = printValues;
    func(100, 200, 300);
    Display disp = printValues;
    disp(400, 500, 600);
    return 0;
}
posted @ 2025-03-21 10:28  酸菜馅粘豆包  阅读(21)  评论(0)    收藏  举报