60 C++ 现代C++编程艺术9-function用法
C++ 现代C++编程艺术9 - std::function
的5种核心用法
文章目录
- C++ 现代C++编程艺术9 - `std::function`的5种核心用法
- 1. 封装普通函数(基础回调)🔧
- 2. 存储Lambda表达式(动态行为)🐑
- 3. 绑定对象成员函数(面向对象集成)🏗️
- 4. 实现函数组合(高阶函数)🔄
- 5. 作为容器元素(回调集合)🧩
1. 封装普通函数(基础回调)🔧
场景:实现事件驱动架构
#include <functional>// 声明函数类型
void LogEvent(const std::string& msg) {std::cout << "[EVENT] " << msg << std::endl;
}int main() {// 封装普通函数std::function<void(const std::string&)> callback = LogEvent;callback("System started"); // 输出: [EVENT] System started
}
优势:
- 统一函数签名,实现松耦合设计
- 适用于GUI事件、网络请求回调等场景
2. 存储Lambda表达式(动态行为)🐑
场景:运行时策略选择
std::function<int(int, int)> operation;// 运行时决定运算逻辑
if (user_choice == "add") {operation = [](int a, int b) { return a + b; };
} else {operation = [](int a, int b) { return a * b; };
}std::cout << operation(3, 4); // 输出7或12
优势:
- 捕获上下文变量(值/引用)
- 替代策略模式,减少类层次复杂度
3. 绑定对象成员函数(面向对象集成)🏗️
class Sensor {
public:float read() const { return 42.5f; }
};int main() {Sensor tempSensor;// 绑定对象成员函数std::function<float()> reader = std::bind(&Sensor::read, &tempSensor);std::cout << "Temperature: " << reader(); // 输出42.5
}
最佳实践:
- 使用
std::bind
时务必传递对象指针(避免悬空引用) - 优先用Lambda替代:
[&] { return tempSensor.read(); }
4. 实现函数组合(高阶函数)🔄
场景:数据处理流水线
// 函数组合工具
auto compose = [](auto f, auto g) {return [f,g](auto x) { return f(g(x)); };
};std::function<int(int)> square = [](int x){ return x*x; };
std::function<int(int)> increment = [](int x){ return x+1; };// 组合函数: (x+1)^2
auto pipeline = compose(square, increment);
std::cout << pipeline(3); // 输出16 ( (3+1)^2 )
进阶技巧:
- 结合
std::bind
实现参数重组:
auto fn = std::bind(compose, std::placeholders::_1, increment);
5. 作为容器元素(回调集合)🧩
场景:观察者模式/插件系统
std::vector<std::function<void(int)>> listeners;// 添加监听器
listeners.push_back([](int data) { std::cout << "Logger: " << data << "\n";
});
listeners.push_back([](int data) {if(data > 100) alert_system();
});// 触发事件
void notify(int event_data) {for (auto& listener : listeners) {listener(event_data); // 依次调用所有回调 }
}
⚠️关键优势:
- 支持动态添加/移除回调函数
- 比虚函数接口更轻量(无vtable开销)
⚠️ 使用注意事项
-
性能优化
- 高频调用场景避免小型
std::function
(内联Lambda更优) - 移动语义替代拷贝:
callbacks.push_back(std::move(my_function))
- 高频调用场景避免小型
-
安全性
std::function<void()> unsafe_func; if (unsafe_func) { // 必须检查空状态!unsafe_func(); // 否则抛出bad_function_call }
-
内存管理
// 捕获大对象时使用智能指针 auto big_data = std::make_shared<DataSet>(); auto processor = [big_data] { /*...*/ };