std::function
对象
std::function
是C++11提供的一个通用的可调用对象容器,能统一保存各种可调用对象,包括普通函数、Lambda表达式、函数对象以及绑定表达式。它实现了类型擦除,使得不同类型的可调用对象可以通过统一的接口进行操作。
定义与使用
#include <iostream>
#include <functional>// 普通函数
int add(int a, int b) {return a + b;
}// 函数对象
struct Multiply {int operator()(int a, int b) const {return a * b;}
};int main() {// 封装普通函数std::function<int(int, int)> func1 = add;std::cout << "Add: " << func1(3, 4) << std::endl; // 输出: Add: 7// 封装Lambda表达式std::function<int(int, int)> func2 = [](int a, int b) -> int {return a - b;};std::cout << "Subtract: " << func2(10, 4) << std::endl; // 输出: Subtract: 6// 封装函数对象Multiply multiply;std::function<int(int, int)> func3 = multiply;std::cout << "Multiply: " << func3(3, 4) << std::endl; // 输出: Multiply: 12return 0;
}
特点
- 类型擦除: 可以存储任何符合签名的可调用对象。
- 灵活性: 支持动态改变存储的可调用对象。
- 性能开销: 相比于直接使用函数指针或Lambda,
std::function
可能带来一定的性能开销,尤其是在频繁调用时。
用法场景
- 回调函数的传递。
- 事件处理系统。
- 策略模式的实现。
示例:回调机制
#include <iostream>
#include <functional>// 定义回调类型
using Callback = std::function<void(int)>;// 触发事件的函数
void triggerEvent(Callback cb, int value) {// 事件发生,调用回调cb(value);
}int main() {// 使用Lambda作为回调triggerEvent([](int x) {std::cout << "事件触发,值为: " << x << std::endl;}, 42); // 输出: 事件触发,值为: 42// 使用仿函数作为回调struct Printer {void operator()(int x) const {std::cout << "Printer打印值: " << x << std::endl;}} printer;triggerEvent(printer, 100); // 输出: Printer打印值: 100return 0;
}
存储和调用不同类型的可调用对象
std::function
可以在容器中存储各种不同类型的可调用对象,只要它们符合指定的签名。
#include <iostream>
#include <functional>
#include <vector>int add(int a, int b) {return a + b;
}struct Multiply {int operator()(int a, int b) const {return a * b;}
};int main() {std::vector<std::function<int(int, int)>> operations;// 添加不同类型的可调用对象operations.emplace_back(add); // 普通函数operations.emplace_back(Multiply()); // 仿函数operations.emplace_back([](int a, int b) -> int { return a - b; }); // Lambda// 执行所有操作for(auto& op : operations) {std::cout << op(10, 5) << " "; // 输出: 15 50 5}std::cout << std::endl;return 0;
}
额外知识
- std::function的类型
#include <functional>
#include <type_traits>int main() {std::function<void(int)> func;static_assert(std::is_same<decltype(func), std::function<void(int)>>::value, "类型不同!");
}