Bootstrap

【C++】std::function

std::function学习笔记

基本概念

std::function是一个函数封装器,可以将任何可调用对象(如函数、函数指针、Lambda表达式、成员函数指针等)包装成一个可调用对象,从而实现对各种类型可调用对象的统一管理和操作。

内部原理

std::function的内部原理主要依赖于模板和多态。它通过模板参数推导和类型擦除的技术,将各种类型的可调用对象转换成一个通用的内部结构体对象,从而实现了对可调用对象的统一封装和管理。

应用场景

  • 回调函数管理std::function可以用于管理回调函数,将多个回调函数封装成一个std::function对象,统一管理和调用。
  • 函数参数和返回值std::function可以作为函数的参数或者返回值,用于传递和返回可调用对象,实现函数的动态性和灵活性。
  • 事件处理机制std::function可以用于实现观察者模式、事件处理机制等场景,将多个事件处理函数封装成一个std::function对象,统一管理和调用。

示例代码

#include <iostream>
#include <functional>

// 回调函数管理示例
void callback1() {
    std::cout << "Callback 1 called" << std::endl;
}

void callback2() {
    std::cout << "Callback 2 called" << std::endl;
}

void testCallback(std::function<void()> callback) {
    callback();
}

// 函数参数和返回值示例
int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

// 事件处理机制示例
class Event {
public:
    using EventHandler = std::function<void()>;

    void registerHandler(EventHandler handler) {
        handlers.push_back(handler);
    }

    void triggerEvent() {
        for (auto& handler : handlers) {
            handler();
        }
    }

private:
    std::vector<EventHandler> handlers;
};

int main() {
    // 回调函数管理示例
    testCallback(callback1);
    testCallback(callback2);

    // 函数参数和返回值示例
    std::function<int(int, int)> func;
    func = add;
    std::cout << "Addition result: " << func(5, 3) << std::endl;

    func = subtract;
    std::cout << "Subtraction result: " << func(5, 3) << std::endl;

    // 事件处理机制示例
    Event event;
    event.registerHandler([]() { std::cout << "Event handler 1 called" << std::endl; });
    event.registerHandler([]() { std::cout << "Event handler 2 called" << std::endl; });
    event.triggerEvent();

    return 0;
}

使用技巧

  • 与Lambda表达式配合使用std::function与Lambda表达式一起使用,可以实现简洁的函数封装和传递。
  • 与std::bind函数配合使用std::function可以与std::bind函数一起使用,将可调用对象绑定到特定的参数上,生成新的可调用对象。

示例代码

#include <iostream>
#include <functional>

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

int main() {
    // 使用Lambda表达式
    std::function<void()> lambdaFunc = []() { std::cout << "Lambda function called" << std::endl; };
    lambdaFunc();

    // 使用std::bind函数
    auto boundFunc = std::bind(add, 5, std::placeholders::_1);
    std::cout << "Result of bound function: " << boundFunc(3) << std::endl;

    return 0;
}

实战案例

示例一:实现一个简单的观察者模式
#include <iostream>
#include <functional>
#include <vector>

class Observer {
public:
    virtual void update() = 0;
};

class Subject {
public:
    void addObserver(Observer* observer) {
        observers.push_back(observer);
    }

    void notifyObservers() {
        for (auto& observer : observers) {
            observer->update();
        }
    }

private:
    std::vector<Observer*> observers;
};

class ConcreteObserver : public Observer {
public:
    ConcreteObserver(const std::string& name) : name(name) {}

    void update() override {
        std::cout << "Observer " << name << " received update" << std::endl;
    }

private:
    std::string name;
};

int main() {
    Subject subject;
    ConcreteObserver observer1("Observer 1");
    ConcreteObserver observer2("Observer 2");

    subject.addObserver(&observer1);
    subject.addObserver(&observer2);

    subject.notifyObservers();

    return 0;
}
示例二:实现一个简单的函数调度器
#include <iostream>
#include <functional>
#include <vector>

class Scheduler {
public:
    using Task = std::function<void()>;

    void addTask(Task task) {
        tasks.push_back(task);
    }

    void runTasks() {
        for (auto& task : tasks) {
            task();
        }
    }

private:
    std::vector<Task> tasks;
};

void task1() {
    std::cout << "Task 1 executed" << std::endl;
}

void task2() {
    std::cout << "Task 2 executed" << std::endl;
}

int main() {
    Scheduler scheduler;
    scheduler.addTask(task1);
    scheduler.addTask(task2);

    scheduler.runTasks();

    return 0;
}

这些示例展示了std::function在实际开发中的广泛应用,从简单的函数封装到实现观察者模式和函数调度器等功能。通过std::function,我们可以实现函数的动态调用、统一管理和灵活传递,提高代码的可读性和可维护性。

;