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
,我们可以实现函数的动态调用、统一管理和灵活传递,提高代码的可读性和可维护性。