C++11 std::function 用法详解:从基础到进阶实践

周末不加班
周末不加班
发布时间:2026-10-16| 5人浏览过
原创

std::function 是 C++11 引入的一种通用多态函数包装器,能够存储、封装并调用各种可调用对象(如普通函数、Lambda 表达式、成员函数指针等)。它提供了类型擦除能力,使得在不同上下文中统一处理函数逻辑成为可能。

一、std::function 基础介绍

std::function 的核心作用是屏蔽底层可调用对象的差异,提供一个统一的接口进行调用。其基本定义需要指定返回值类型和参数类型:

template<typename RetType>
class RetType {
public:
    // ...
};
std::function<Return_Type(Parameter_Types)> var_name;

关键特性:

  • 类型擦除:可以容纳任意满足签名要求的可调用类型。
  • 空值检测:可以使用 bool 运算符检查对象是否为空(即是否绑定了有效的可调用对象)。
  • 包含头文件:使用时需引用 #include <functional>。

第 1 步:基础声明与赋值

可以通过函数指针或类成员函数初始化 std::function:

#include <iostream>
#include <functional>

// 普通函数
int func(int x, int y) { return x + y; }

// 类结构
struct A {
    int mem_func(int x) { return x * x; }
};

void example() {
    // 绑定普通函数
    std::function<int(int, int)> f = func;
    
    // 绑定成员函数指针(注意:第一个参数通常隐含为 this 指针或实例引用)
    std::function<int(A*, int)> f2 = &A::mem_func;
}

第 2 步:状态检查与安全调用

在调用前判断对象是否为空是防止运行时错误的关键步骤:

std::function<int(int, int)> f_empty;

if (f_empty)
    std::cout << f_empty(1, 2) << std::endl;
else
    std::cout << "f is empty" << std::endl;

二、进阶使用方法

第 3 步:结合 std::bind 使用

当需要固定部分参数或调整参数顺序时,std::bind 是常用搭档。以下示例展示了如何使用占位符 std::placeholders::_1 来构建灵活的绑定关系:

#include <iostream>
#include <functional>

using namespace std::placeholders;

void test1() { std::cout << "function called" << std::endl; }
int test2(int i) { return i * 10; }
int test3(int i, int j) { return i + j; }

struct A {
    void foo(int i) { std::cout << i << std::endl; }
};

int main() {
    // 1. 无参函数绑定
    std::function<void()> fn1 = std::bind(test1);
    
    // 2. 单参数映射
    std::function<int(int)> fn2 = std::bind(test2, _1);
    
    // 3. 双参数映射
    std::function<int(int, int)> fn3 = std::bind(test3, _1, _2);
    
    // 4. 绑定固定参数 (currying/偏应用)
    std::function<int(int)> fn4 = std::bind(test3, 3, _1);
    std::function<int()> fn5 = std::bind(test3, 3, 4);
    
    // 5. 绑定对象成员函数
    A a;
    std::function<void(int)> fn6 = std::bind(&A::foo, &a, _1);
    
    // 执行验证
    fn1();          // 输出: function called
    std::cout << fn2(1) << std::endl;    // 输出: 10
    std::cout << fn3(2, 3) << std::endl; // 输出: 5
    std::cout << fn4(3) << std::endl;    // 输出: 6
    std::cout << fn5() << std::endl;     // 输出: 7
    fn6(8);         // 输出: 8
    
    return 0;
}

第 4 步:存储 Lambda 表达式

Lambda 表达式是现代 C++ 中最常见的 std::function 来源。它可以捕获当前作用域的变量,实现更复杂的状态管理:

// 简单的 Lambda 加法
auto lambda_add = [](int a, int b) { return a + b; };
std::function<int(int, int)> add_fn = lambda_add;
std::cout << add_fn(10, 20) << std::endl; // 输出: 30

第 5 步:结合智能指针管理资源

虽然 std::function 本身不负责内存所有权,但在某些高级场景下,可以将具有特定生命周期管理的对象包装入其中。需要注意的是,标准的 std::make_shared 并不直接用于创建 std::function 对象,而是用于创建被包装的对象。下面的示例演示了如何通过工厂模式或特定的初始化方式结合智能指针,但核心重点在于理解 std::function 的泛型存储能力:

// 典型用法:存储指向具体功能实现的共享指针
// 注意:这里的写法旨在展示如何存储一个通用的函数子对象类型
// 并非标准库直接提供 make_shared<std::function> 的构造方式,
// 更多时候我们直接使用 lambda 捕获智能指针来实现资源管理。

std::shared_ptr<int> resource = std::make_shared<int>(100);
std::function<int()> get_resource = [&]() { return *resource; };
std::cout << get_resource() << std::endl; // 输出: 100

三、注意事项与限制

  1. 无法重载函数:std::function 只能针对具体的签名(返回类型+参数列表)创建实例。如果存在同名重载函数,必须明确指定类型或通过 Lambda 进行转发。
  2. 性能开销:由于涉及类型擦除和多态分发,std::function 的调用速度略低于直接的函数指针调用或编译器能内联优化的 Lambda。在高性能计算瓶颈中需权衡使用。
  3. 循环引用:在 Lambda 捕获时使用 this 指针需谨慎,避免与类内部其他持有该 std::function 成员的逻辑产生循环引用导致内存泄漏。建议使用 weak_ptr 或确保作用域清晰。

如需查阅更详细的 API 文档和标准规范,推荐参考以下权威链接:

  • C++11/14/17/20 Standard Reference on cppreference.com
  • cplusplus.com functional reference

以上就是 C++11 中 std::function 基础用法详解的详细内容,更多关于 C++ std::function 的技巧资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。