std::function 是 C++11 引入的可调用对象包装器,定义于 functional 头文件中,能统一封装函数、lambda、函数对象、成员函数等可调用实体。它通过模板语法 std::function 声明,支持类型安全的调用封装,常用于回调机制、事件处理等场景,并可检查空状态以确保有效性。

在C++中,函数对象(function object)是一种可以像函数一样被调用的对象。而 std::function 是 C++11 引入的一个通用可调用对象包装器,它能够封装各种类型的可调用实体,包括普通函数、函数指针、lambda 表达式、函数对象(重载了 operator() 的类对象)、以及成员函数指针等。
什么是 std::function?
std::function 定义在头文件 functional 中,是一个模板类,用于统一和泛化对可调用对象的处理。它的主要作用是提供一个类型安全且统一的接口来保存、传递和调用不同形式的可调用对象。
基本语法如下:
std::function 变量名;如何使用 std::function 包装不同类型的可调用对象?
下面展示几种常见的可调用对象如何通过 std::function 进行包装。
立即学习“C++免费学习笔记(深入)”;
1. 包装普通函数
普通函数是最简单的可调用对象。
#include#include iostream>
void greet() {
std::cout }
int add(int a, int b) {
return a + b;
}
int main() {
std::function
f1(); // 输出: Hello, world!
std::function
std::cout
return 0;
}
2. 包装 Lambda 表达式
Lambda 是最常与 std::function 配合使用的特性之一。
auto lambda = [](int x) { return x * x; };std::function
std::cout
也可以直接赋值 lambda:
std::function3. 包装函数对象(仿函数)
自定义类重载了 operator() 后,其实例就是函数对象。
struct Multiply {int operator()(int a, int b) const {
return a * b;
}
};
std::function
std::cout
4. 包装类成员函数
成员函数需要绑定对象实例才能调用,通常配合 std::bind 或 lambda 使用。
class Calculator {public:
int multiply(int a, int b) {
return a * b;
}
};
Calculator calc;
std::function
std::cout
// 更常用的是绑定具体对象
std::function
std::cout
或者使用 lambda 简化:
std::functionreturn calc.multiply(a, b);
};
5. std::function 的空状态检查
std::function 可以像指针一样检查是否包含有效的可调用对象。
std::functionif (!f) {
std::cout }
f = []{ std::cout if (f) {
f(); // 调用
}
6. 在回调机制中的应用
std::function 常用于实现回调函数,提升代码灵活性。
class EventManager {private:
std::function
public:
void setCallback(std::function
callback = cb;
}
void trigger() {
if (callback) callback();
}
};
EventManager em;
em.setCallback([]{ std::cout red!" em.trigger(); // 输出: Callback triggered!
性能与注意事项
std::function 提供了极大的灵活性,但相比直接调用函数或函数对象,它有一定的运行时开销,因为它内部使用了类型擦除(type erasure)技术。
- 不要在性能极度敏感的循环中频繁调用 std::function 包装的函数。
- 避免将 std::function 作为频繁调用的内联函数参数。
- 它可以持有捕获外部变量的 lambda,需注意生命周期问题,防止悬空引用。
基本上就这些。std::function 是现代 C++ 实现高内聚、低耦合设计的重要工具,尤其适合用于策略模式、事件回调、异步任务等场景。掌握它,能让代码更清晰、更灵活。










