std::function 用法详解

`std::function` 是 C++11 引入的通用函数包装器(定义于 `` 头文件),可存储、复制和调用任何**可调用对象**(函数、lambda 表达式、函数指针、仿函数、绑定表达式等),是回调机制、事件处理等场景的核心工具。

## 基本用法:定义与调用

`std::function` 的模板参数为**函数签名**(返回类型 + 参数列表),格式为:

“` text

std::function<返回类型(参数类型1, 参数类型2, ...)>

“`

### 示例:包装不同类型的可调用对象

“`cpp

#include
#include

// 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 func1 = add;

// 输出:5
std::cout << func1(2, 3) << std::endl; // 包装仿函数 std::function func2 = Multiply{};

// 输出:6
std::cout << func2(2, 3) << std::endl; // 包装 lambda 表达式 std::function 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 func4 = sub_ptr;

// 输出:2
std::cout << func4(5, 3) << std::endl; return 0; } ``` ## 核心特性:存储与传递可调用对象 `std::function` 的核心价值是**统一不同可调用对象的类型**,便于存储和传递(如作为函数参数、返回值、容器元素)。 ### 1. 作为函数参数(回调函数场景) ```cpp // 接收 std::function 作为参数,实现通用回调 void process(int a, int b, std::function 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. 作为函数返回值 ```cpp // 根据条件返回不同的运算函数 std::function 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. 作为容器元素 ```cpp #include

int main()
{
std::vector> 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`,固定部分参数,返回新的可调用对象。 ```cpp #include

// 原函数: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 func = bindFunc;

// 10 + 20 + 30 = 60
std::cout << func(30) << std::endl; return 0; } ``` ### 4. 绑定成员函数 `std::function` 可通过绑定具体对象或指针包装类的成员函数。 ```cpp #include
#include

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 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. 注意事项 1. **性能开销**:`std::function` 内部通过类型擦除实现,调用时会有轻微的性能损耗(比直接调用函数指针略慢),但通常可忽略。 2. **生命周期管理**:若包装的是捕获了引用的 lambda 或绑定了局部对象的 `std::bind` 表达式,需确保引用的对象生命周期长于 `std::function`,否则会导致未定义行为。 3. **不可拷贝的可调用对象**:`std::function` 要求存储的可调用对象是**可拷贝的**,若对象不可拷贝(如 `std::unique_ptr` 捕获到 lambda 中),则无法存储(C++17 起可部分支持移动语义)。 4. **与 lambda 的配合**:无捕获的 lambda 可隐式转换为函数指针,而有捕获的 lambda 只能通过 `std::function` 包装。

此条目发表在C/C++分类目录。将固定链接加入收藏夹。