1. 为什么需要std::function
在C++98时代,我们处理回调函数主要有三种方式:函数指针、仿函数(Functor)和虚函数。这三种方式各有优缺点:
- 函数指针:效率高但无法捕获上下文状态
- 仿函数:需要定义完整的类,代码冗长
- 虚函数:运行时多态带来性能开销
C++11引入的std::function完美解决了这些问题。它就像是一个万能函数容器,可以存储任何可调用对象 - 普通函数、成员函数、lambda表达式、bind表达式等。我在实际项目中经常用它来实现事件系统、回调机制和策略模式。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. std::function的核心特性
2.1 类型擦除的魔法
std::function的核心在于类型擦除技术。它通过模板特化和虚函数表,在运行时动态管理各种可调用对象。具体实现上:
cpp复制template<class R, class... Args>
class function<R(Args...)> {
// 内部通过基类指针实现类型擦除
callable_base* callable;
};
这种设计使得std::function有16-32字节的大小(取决于实现),比函数指针略大但比虚函数开销小得多。
2.2 使用示例对比
传统方式:
cpp复制// 函数指针
void (*func_ptr)(int) = &foo;
// 仿函数
struct MyFunctor {
void operator()(int) { /*...*/ }
};
MyFunctor functor;
C++11方式:
cpp复制std::function<void(int)> f;
// 可以接受各种可调用对象
f = &foo; // 函数指针
f = MyFunctor(); // 仿函数
f = [](int x){ // lambda
std::cout << x;
};
3. 实际工程中的应用技巧
3.1 作为回调参数
在事件驱动系统中,std::function是完美的回调载体:
cpp复制class Button {
public:
using Callba
