C++11中的bind绑定器和function函数对象

一、std::bind绑定器的基本概念

C++11 中的 std::bind 是一个函数绑定工具,用于将函数、成员函数或函数对象与其参数绑定,生成一个新的可调用对象。它提供了灵活的参数适配功能,常用于回调、延迟调用和参数顺序调整等场景。

二、std::bind绑定器的基本用法

1. 头文件和命名空间

#include <functional>
using namespace std::placeholders;  // 用于占位符 _1, _2...

2. 基本用法
绑定普通函数:

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

int main() {
    auto bound = std::bind(func, 10, _1);  // 绑定第一个参数为10
    bound(20);  // 输出: 10, 20
}

调整参数个数:

auto bound = std::bind(func, _1, _2);  // 交换参数顺序
bound(10, 20);  // 输出: 10, 20

绑定成员函数:

class MyClass {
public:
    void memberFunc(int a) {
        std::cout << "Value: " << a << std::endl;
    }
};

int main() {
    MyClass obj;
    auto bound = std::bind(&MyClass::memberFunc, &obj, _1);
    bound(42);  // 输出: Value: 42
}

绑定函数对象:

struct Functor {
    void operator()(int a, int b) {
        std::cout << a + b << std::endl;
    }
};

int main() {
    Functor f;
    auto bound = std::bind(f, 3, _1);
    bound(5);  // 输出: 8
}

3. 参数传递方式

  • 按值传递:默认行为。
  • 按引用传递:使用 std::ref 或 std::cref。
void modify(int& x) { x *= 2; }

int main() {
    int value = 5;
    auto bound = std::bind(modify, std::ref(value));
    bound();  // value 变为 10
}

4. 实际应用场景
回调函数:

void onEvent(int eventId, const std::string& msg) {
    std::cout << "Event " << eventId << ": " << msg << std::endl;
}

int main() {
    auto callback = std::bind(onEvent, 1001, _1);
    callback("Connection established");  // 输出: Event 1001: Connection established
}

STL算法适配:

// 将 vector 中的值与固定值比较
std::vector<int> vec = {1, 2, 3, 4, 5};
int threshold = 3;
auto isAbove = std::bind(std::greater<int>(), _1, threshold);
int count = std::count_if(vec.begin(), vec.end(), isAbove);  // 结果为2(4和5)

三、std::function函数对象的基本概念

std::function 是 C++11 引入的一个通用函数封装器,用于存储、传递和调用任何可调用对象(如普通函数、成员函数、Lambda 表达式、函数对象等)。它提供了一种类型安全的方式来处理各种可调用对象,常用于回调机制、事件处理等场景。

四、std::function函数对象的基本用法

1. 头文件

#include <functional>

2. 基本用法
std::function 的模板参数形式为:

std::function<返回值类型(参数类型1, 参数类型2, ...)>

封装普通函数:

#include <iostream>
#include <functional>

void print(int x) {
    std::cout << "Value: " << x << std::endl;
}

int main() {
    std::function<void(int)> func = print;
    func(42);  // 输出: Value: 42
}

封装 Lambda 表达式:

#include <iostream>
#include <functional>

int main() {
    std::function<int(int, int)> add = [](int a, int b) {
        return a + b;
    };

    std::cout << add(3, 5) << std::endl;  // 输出: 8
}

封装成员函数:

#include <iostream>
#include <functional>

class MyClass {
public:
    void print(int x) const {
        std::cout << "Value: " << x << std::endl;
    }
};

int main() {
    MyClass obj;
    std::function<void(const MyClass&, int)> func = &MyClass::print;
    func(obj, 42);  // 输出: Value: 42
}

封装函数对象:

#include <iostream>
#include <functional>

class Add {
    int operator()(int a, int b) const {
        return a + b;
    }
};

int main() {
    std::function<int(int, int)> func = Add();
    std::cout << func(3, 5) << std::endl;  // 输出: 8
}

五、std::bind和std::function结合使用

std::function 可以存储 std::bind 绑定的可调用对象:

#include <iostream>
#include <functional>

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

int main() {
    auto bound = std::bind(print, 10, std::placeholders::_1);
    std::function<void(int)> func = bound;
    func(20);  // 输出: 10, 20
}

实际应用场景:

  • 回调机制
#include <iostream>
#include <functional>

class Button {
public:
    void setOnClick(std::function<void()> callback) {
        onClick = callback;
    }

    void click() {
        if (onClick) {
            onClick();
        }
    }

private:
    std::function<void()> onClick;
};

int main() {
    Button btn;
    btn.setOnClick([]() {
        std::cout << "Button clicked!" << std::endl;
    });

    btn.click();  // 输出: Button clicked!
}
  • 事件处理
#include <iostream>
#include <functional>
#include <map>

class EventSystem {
public:
    using EventHandler = std::function<void()>;

    void registerEvent(const std::string& eventName, EventHandler handler) {
        events[eventName] = handler;
    }

    void triggerEvent(const std::string& eventName) {
        if (events.find(eventName) != events.end()) {
            events[eventName]();
        }
    }

private:
    std::map<std::string, EventHandler> events;
};

int main() {
    EventSystem system;
    system.registerEvent("start", []() {
        std::cout << "Start event triggered!" << std::endl;
    });

    system.triggerEvent("start");  // 输出: Start event triggered!
}

注意事项:
空 std::function需要做检查

std::function<void()> func;
if (func) {
    func();  // 只有 func 不为空时才调用
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值