std::function 是 C++11 引入的通用函数包装器(定义于 <functional> 头文件),可存储、复制和调用任何可调用对象(函数、lambda 表达式、函数指针、仿函数、绑定表达式等),是回调机制、事件处理等场景的核心工具。
基本用法:定义与调用
std::function 的模板参数为函数签名(返回类型 + 参数列表),格式为:
std::function<返回类型(参数类型1, 参数类型2, ...)>
示例:包装不同类型的可调用对象
#include
<functional>
#include
<iostream>
// 1. 普通函数
int add(int a, int b)
{
return a + b;
}
// 2. 仿函数(重载 operator() 的结构体)
struct Multiply
{
int operator()(int a, int b) { return a * b; }
};
int main()
{
// 包装普通函数
std::function<int(int, int)> func1 = add;
// 输出:5
std::cout << func1(2, 3) << std::endl;
// 包装仿函数
std::function<int(int, int)> func2 = Multiply{};
// 输出:6
std::cout << func2(2, 3) << std::endl;
// 包装 lambda 表达式
std::function<int(int, int)> func3 = [](int a, int b) { return a - b; };
// 输出:3
std::cout << func3(5, 2) << std::endl;
// 包装函数指针
int (*sub_ptr)(int, int) = [](int a, int b) { return a - b; };
// lambda 转换为函数指针(无捕获时)
std::function<int(int, int)> func4 = sub_ptr;
// 输出:2
std::cout << func4(5, 3) << std::endl;
return 0;
}
核心特性:存储与传递可调用对象
std::function 的核心价值是统一不同可调用对象的类型,便于存储和传递(如作为函数参数、返回值、容器元素)。
1. 作为函数参数(回调函数场景)
// 接收 std::function 作为参数,实现通用回调
void process(int a, int b, std::function<int(int, int)> op)
{
std::cout << "结果: " << op(a, b) << std::endl;
}
int main()
{
// 普通函数作为回调
process(10, 5, add);
// 仿函数作为回调
process(10, 5, Multiply{});
// lambda 作为回调
process(10, 5, [](int a, int b) { return a / b; });
return 0;
}
2. 作为函数返回值
// 根据条件返回不同的运算函数
std::function<int(int, int)> GetOperator(char op)
{
switch (op)
{
case '+':
return add;
case '*':
return Multiply{};
case '-':
return [](int a, int b) { return a - b; };
default:
return [](int, int) { return 0; };
}
}
int main()
{
auto op = GetOperator('*');
// 输出:12
std::cout << op(3, 4) << std::endl;
return 0;
}
3. 作为容器元素
#include
<vector>
int main()
{
std::vector<std::function<int(int)>> funcs;
// 乘以 2
funcs.push_back([](int x) { return x * 2; });
// 加 10
funcs.push_back([](int x) { return x + 10; });
// 平方
funcs.push_back([](int x) { return x * x; });
int x = 3;
for (auto& f : funcs)
{
std::cout << f(x) << " "; // 输出:6 13 9
}
return 0;
}
3. 结合 std::bind 绑定参数
std::function配合std::bind,固定部分参数,返回新的可调用对象。
#include
<functional>
// 原函数:3个参数
int sum(int a, int b, int c)
{
return a + b + c;
}
int main()
{
// 绑定前两个参数为 10 和 20,仅保留最后一个参数
// std::placeholders::_n 表示“第n个未绑定的参数”,调用时需传入。
auto bindFunc = std::bind(sum, 10, 20, std::placeholders::_1);
// 用 std::function 包装绑定后的函数(此时只需 1 个参数)
std::function<int(int)> func = bindFunc;
// 10 + 20 + 30 = 60
std::cout << func(30) << std::endl;
return 0;
}
4. 绑定成员函数
std::function 可通过绑定具体对象或指针包装类的成员函数。
#include
<functional>
#include
<iostream>
class Math
{
public:
int pow(int a, int b)
{
// 成员函数
int res = 1;
for (int i = 0; i < b; ++i)
{
res *= a;
}
return res;
}
};
int main()
{
Math m;
// 包装成员函数:需传入对象指针 + 成员函数地址
// 成员函数的第一个隐含参数是 this指针,因此绑定需显式传入对象(或指针)。
std::function<int(int, int)> func = std::bind(&Math::pow, &m,
std::placeholders::_1,
std::placeholders::_2);
// 2^3 = 8
std::cout << func(2, 3) << std::endl;
return 0;
}
总结
1. 主要用法
std::function是C++中统一可调用对象的“万能容器”,主要用法包括:
- 包装函数、lambda、仿函数等可调用对象;
- 作为参数传递(回调函数)、作为返回值(函数工厂)、作为容器元素;
- 结合
std::bind处理参数绑定和成员函数; - 需注意空状态检查和对象生命周期。
2. 注意事项
- 性能开销:
std::function内部通过类型擦除实现,调用时会有轻微的性能损耗(比直接调用函数指针略慢),但通常可忽略。 - 生命周期管理:若包装的是捕获了引用的 lambda 或绑定了局部对象的
std::bind表达式,需确保引用的对象生命周期长于std::function,否则会导致未定义行为。 - 不可拷贝的可调用对象:
std::function要求存储的可调用对象是可拷贝的,若对象不可拷贝(如std::unique_ptr捕获到 lambda 中),则无法存储(C++17 起可部分支持移动语义)。 - 与 lambda 的配合:无捕获的 lambda 可隐式转换为函数指针,而有捕获的 lambda 只能通过
std::function包装。

