C++11的函数包装器std::function使用示例

 更新时间:2024年12月28日 14:51:36   作者:明日cto  
C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解,包括它的基本用法、特点、限制、以及与其他相关机制的对比

C++中的函数包装器(Function Wrapper)是用来封装和管理函数或可调用对象(如函数指针、函数对象、Lambda 表达式等)的工具。它们使得函数的使用更为灵活和通用,常被用于异步编程、事件处理、回调等场景。

C++11引入的 std::function 是最常用的函数包装器。它可以存储任何可调用对象并提供统一的调用接口。以下是关于函数包装器的详细讲解,包括它的基本用法、特点、限制、以及与其他相关机制的对比。

一、std::function 的基本用法

std::function 是 C++ 标准库中的一个模板类,可以存储一个可调用对象,如普通函数、函数指针、Lambda 表达式、或实现了 operator() 的对象。

1. 基本语法

#include <iostream>  
#include <functional>  

void myFunction(int x) {  
    std::cout << "Function called with: " << x << std::endl;  
}  

int main() {  
    std::function<void(int)> func = myFunction; // 包装普通函数  

    func(10); // 输出: Function called with: 10  

    // 也可以包装 Lambda 表达式  
    func = [](int y) {  
        std::cout << "Lambda called with: " << y << std::endl;  
    };  

    func(20); // 输出: Lambda called with: 20  

    return 0;  
}

二、如何使用 std::function

1. 存储不同类型的可调用对象

std::function 可以存储任何可以调用的对象,包括函数、Lambda 表达式和函数对象。

#include <iostream>  
#include <functional>  

int add(int a, int b) {  
    return a + b;  
}  

struct Multiply {  
    int operator()(int a, int b) const {  
        return a * b;  
    }  
};  

int main() {  
    std::function<int(int, int)> func;  

    // 包装普通函数  
    func = add;  
    std::cout << "Add: " << func(3, 4) << std::endl; // 输出: Add: 7  

    // 包装函数对象  
    func = Multiply();  
    std::cout << "Multiply: " << func(3, 4) << std::endl; // 输出: Multiply: 12  

    // 包装 Lambda 表达式  
    func = [](int a, int b) { return a - b; };  
    std::cout << "Subtract: " << func(10, 4) << std::endl; // 输出: Subtract: 6  

    return 0;  
}

2. 使用类型推导

C++14引入了泛型Lambda,进一步增强了 std::function 的灵活性:

#include <iostream>  
#include <functional>  

int main() {  
    // 使用 Lambda 表达式的类型推导  
    auto lambda = [](int x) { return x * 2; };  
    std::function<int(int)> func = lambda;  

    std::cout << "Lambda result: " << func(5) << std::endl; // 输出: Lambda result: 10  

    return 0;  
}

三、特点与限制

1. 类型安全

std::function 提供强类型安全,确保传递的可调用对象与指定的函数签名相符。

2. 存储开销

std::function 是一个类型擦除(Type Erasure)机制的实现,它会根据保存的可调用对象的类型动态分配内存。尽管这使得类型更灵活,但也增加了一些运行时开销。

3. 性能考虑

由于类型擦除的特性,std::function 的性能通常低于直接使用函数指针或 Lambda 表达式,特别是在高频调用的场景下。如果对性能有较高要求,建议直接使用函数指针或模板。

四、结合 std::bind

std::bind 是一个C++11引入的函数适配器,允许将某些参数绑定到函数对象或 Lambda 表达式。与 std::function 结合使用可以使代码更灵活。

#include <iostream>  
#include <functional>  

void print(int x, int y) {  
    std::cout << "x: " << x << ", y: " << y << std::endl;  
}  

int main() {  
    // 使用 std::bind 绑定部分参数  
    auto boundFunc = std::bind(print, 10, std::placeholders::_1);  
    
    // `boundFunc` 现在只需要一个参数  
    boundFunc(20); // 输出: x: 10, y: 20  

    return 0;  
}

五、结合标准库的异步操作

在使用异步处理时,std::function 可以存储要在新线程中执行的函数。

#include <iostream>  
#include <functional>  
#include <thread>  

void asyncTask(int id) {  
    std::cout << "Task " << id << " is running." << std::endl;  
}  

int main() {  
    // 声明 std::function  
    std::function<void(int)> task = asyncTask;  

    // 创建新线程  
    std::thread t(task, 1);  
    t.join(); // 等待线程结束  

    return 0;  
}

六、总结

到此这篇关于C++11的函数包装器std::function使用示例的文章就介绍到这了,更多相关C++11的函数包装器std::function内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用C语言实现动态数组Vector

    使用C语言实现动态数组Vector

    这篇文章主要为大家详细介绍了使用C语言实现动态数组Vector的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • 快速了解Boost.Asio 的多线程模型

    快速了解Boost.Asio 的多线程模型

    这篇文章主要介绍了Boost.Asio 的多线程模型的相关知识,文中代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下
    2020-06-06
  • C语言 从根本上理解指针

    C语言 从根本上理解指针

    C语言这门课程在计算机的基础教学中一直占有比较重要的地位,然而要想突破C语言的学习,对指针的掌握是非常重要的,本文将具体针对指针的基础做详尽的介绍
    2022-04-04
  • VC小技巧汇总之控件技巧

    VC小技巧汇总之控件技巧

    这篇文章主要介绍了VC小技巧汇总之控件技巧,对于VC的开发很有借鉴价值,需要的朋友可以参考下
    2014-07-07
  • C++11中的智能指针和垃圾回收使用

    C++11中的智能指针和垃圾回收使用

    本文主要介绍了C++11中的智能指针和垃圾回收使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • C语言实现简单学生管理系统

    C语言实现简单学生管理系统

    这篇文章主要为大家详细介绍了C语言实现简单学生管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • 详解C/C++内存管理

    详解C/C++内存管理

    内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,今天给大家分享C/C++内存管理的实例代码,需要的朋友参考下吧
    2021-06-06
  • C语言判断字符串是否以str2开头代码

    C语言判断字符串是否以str2开头代码

    这里给大家分享的是一个使用C语言实现的判断字符串中是否以某字符开头或者结尾的代码,非常的简单实用,希望大家能够喜欢
    2017-05-05
  • Matlab控制电脑摄像实现实时人脸检测和识别详解

    Matlab控制电脑摄像实现实时人脸检测和识别详解

    人脸识别过程主要由四个阶段组成:人脸检测、图像预处理、面部特征提取和特征识别。这篇文章主要介绍了如何使用MATLAB控制笔记本电脑的摄像头,并进行实时人脸检测和识别,需要的可以参考一下
    2022-10-10
  • C语言中动态内存管理图文详解

    C语言中动态内存管理图文详解

    在编写程序时,通常并不知道需要处理的数据量,或者难以评估所需处理数据量的变动程度,下面这篇文章主要给大家介绍了关于C语言中动态内存管理的相关资料,需要的朋友可以参考下
    2022-06-06

最新评论