C++11(5)

news2024/11/14 13:48:54

目录

12。function包装器

用法

function的应用

13。bind绑定

bind的应用——计算利息


万众瞩目的C++11它又来了,本章将继续讲解C++11更新的内容,欢迎观看!!!

12。function包装器

function包装器 也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。

用法

#include<iostream>
using namespace std;
#include<vector>

#include<functional>//仿函数也在这个头文件里面

//function包装器
//function包装器 也叫作适配器。
//C++中的function本质是一个类模板,也是一个包装器。
//使用function包装器时需要头文件#include<functional>

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

struct Functor
{
public:
    int operator() (int a, int b)
    {
        return a + b;
    }
};

class Plus
{
public:
    static int plusi(int a, int b)
//没有this指针
    {
        return a + b;
    }

    double plusd(double a, double b)
    {
        return a + b;
    }
};

int main()
{
  
 // 包装可调用对象
    //任何可以调用的对象都可以包装,什么函数指针(函数名),仿函数,lambda,主要用于包装函数
    function<int(int, int)> f1 = f;
    cout << f1(4, 5) << endl;
  
 //可以看到包装器的用法
    //function<包装对象的返回值(包装对象的参数的类型)> 包装器对象 = 函数指针(函数名)或仿函数对象或lambda对象
 
   // 包装静态成员函数(没有this指针)
    function<int(int, int)> f2 = Plus::plusi;//可加可不加&
    cout << f2(2, 3) << endl;
  
 // 包装非静态成员函数(有this指针)
    Plus pd;
    function<double(Plus*, double, double)> f5 = &Plus::plusd;
//成员函数有一个this指针所以需要多一个变量类型
    cout << f5(&pd, 1.1, 2.2) << endl;                       //包装成员函数时必须加上&(语法规定)
    //传匿名对象也可以,因为这里的this对于包装器的作用主要是为了找到这个成员函数在哪里,自然指针可以帮助找到,匿名对象也可以的,这里和类型就没有关系了
    function<double(Plus, double, double)> f7 = &Plus::plusd;
    cout << f7(Plus(), 1.1, 2.2) << endl;
    
// 包装仿函数
    function<int(int, int)> f3 = Functor();
    cout << f3(2, 3) << endl;
    
//包装lambda对象
    function<int(int, int)> f4 = [](int a, int b) {return a + b; };
    cout << f4(2, 3) << endl;
    return 0;
}

//那这个function有什么实际价值呢
//当一个模板可以实例化出三个类型不同的对象时,由于对象类型不同我们不好处理
//这里的对象比如函数,仿函数,多个lambda对象,我们可以将他们用function
//封装起来,这样只需要保留一个function类型的对象就好处理了
//所以function<()> f也是有类型的

另外上面提到了包装器可以使被包装的类型统一,所以可以解决模板的效率低下,实例化多份的问题。

function的应用

既然上面说了,包装器可以解决模板效率低下的问题和实例化多份使得类型不一致的问题,既然类型不一致如果可以有一个统一的类型来装就可以解决这个问题了。这个在后面智能指针的实现需要特别使用function。

下面是实现逆波兰表达式的程序,我们可以使用lambda进行实现

https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/submissions/

13。bind绑定

std::bind函数定义在头文件中,是一个函数模板,它就像一个函数包装器(适配器),接受一个可 调用对象(callable object),生成一个新的可调用对象来“适应”原对象的参数列表。一般而 言,我们用它可以把一个原本接收N个参数的函数fn,通过绑定一些参数,返回一个接收M个(M 可以大于N,但这么做没什么意义)参数的新函数。同时,使用std::bind函数还可以实现参数顺 序调整等操作。

//bind绑定
//std::bind函数定义在头文件中,是一个函数模板,它就像一个函数包装器(适配器),接受一个可
//调用对象(callable object),生成一个新的可调用对象来“适应”原对象的参数列表。一般而
//言,我们用它可以把一个原本接收N个参数的函数fn,通过绑定一些参数,返回一个接收M个(M
//可以大于N,但这么做没什么意义)参数的新函数。同时,使用std::bind函数还可以实现参数顺
//序调整等操作。
//简单来说就是用来调整函数参数个数和位置的,主要是用来调整参数个数的因为位置没什么好调整的

using placeholders::_1;
using placeholders::_2;

int Sub(int a, int b)
{
    return (a - b) * 10;
}

int SubX(int a, int b, int c)
{
    return (a - b - c) * 10;
}

class Plus
{
public:
    static int plusi(int a, int b)
    {
        return a + b;
    }

    double plusd(double a, double b)
    {
        return a + b;
    }
};

class Rate
{
public:
    Rate(double rate) : _rate(rate)
    {}

    double operator()(double money, int year)
    {
        return money * _rate * year;
    }
private:
    double _rate;
};

int main()
{
    auto it = bind(Sub, _1, _2);
    // bind 本质返回的一个仿函数对象, 所以bind有返回值
    
// 调整参数顺序(不常用)
    // _1代表第一个实参
    // _2代表第二个实参
    //...
    //用法
    //bind由于是一个函数模板,所以可以看成函数,这样它的第一个参数是所要bind的函数指针,接着的参数就是
    //所要绑定的函数参数的第一个实参的位置的代号_1 ... 这些代号在placeholders这个类里面,所以需要使用代号时
    //需要先声明一下(using一下)不然找不到

    cout << it(2, 1) << endl;
    auto its = bind(Sub, _2, _1);
    cout << its(2, 1) << endl;
    // 调整参数个数 (常用)
    //由于bind返回的是新函数对象所以可以通过function再包装
    auto sub1 = bind(Sub, 100, _1);
    cout << sub1(2) << endl;
    auto sub2 = bind(Sub, _1, 100);
    cout << sub2(2) << endl;
    //所以bind一般用于,绑死一些固定参数

    // 分别绑死第123个参数
    auto sub5 = bind(SubX, 100, _1, _2);
    cout << sub5(5, 1) << endl;

    auto sub6 = bind(SubX, _1, 100, _2);
    cout << sub6(5, 1) << endl;

    auto sub7 = bind(SubX, _1, _2, 100);
    cout << sub7(5, 1) << endl;
    //以上函数可以看成经过绑定后均剩下两个参数
    //可以看到这边的实参的位置是指从没有被绑定的参数开始的,然后计算时会绕过被绑定的参数
    //可以看成被bind绑定的参数就消失了,不算参数了,毕竟不需要自己传了

    function<double(Plus, double, double)> f6 = &Plus::plusd;
    Plus pd;
    cout << f6(pd, 1.1, 1.1) << endl;
    cout << f6(Plus(), 1.1, 1.1) << endl;
    //每次这样写比较麻烦,我们可以使用先绑定第一个参数,然后用其返回的是函数对象的特点再进行function包装
    function<double(double, double)> f7 = bind(&Plus::plusd, &pd, _1, _2);//&Plus::plusd,非静态成员函数必须&
    cout << f7(1.1, 1.1) << endl;


    return 0;
}

bind的应用——计算利息

int main()
{
    //bind绑定lambda对象,无论是绑定什么对象,被bind绑定后,bind对象会执行被绑定的函数体的内容
    auto func1 = [](double rate, double monty, int year)->double
        {
            double rat = monty;
            for (int i = 0; i < year; i++)
            {
                rat += rat * rate;//算逐年累计的获利+本金
            }
            return rat - monty;//算出利息
        };
    function<double(double)> func3_1_5 = bind(func1, 0.015, _1, 3);
    function<double(double)> func5_1_5 = bind(func1, 0.015, _1, 5);
    function<double(double)> func10_2_5 = bind(func1, 0.025, _1, 10);
    function<double(double)> func20_3_5 = bind(func1, 0.035, _1, 30);
    //会发现比如算利息这种函数,是不是只需要传入本金就可以了,因为每次利率和年份是固定的
    //所以可以使用绑定绑死,这样可以提高操作效率

    cout << func3_1_5(1000000) << endl;
    cout << func5_1_5(1000000) << endl;
    cout << func10_2_5(1000000) << endl;
    cout << func20_3_5(1000000) << endl;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2150253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据新视界 --大数据大厂之算法在大数据中的核心作用:提升效率与智能决策

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

情感类智能体——你的微信女神

智能体名称&#xff1a;你的微信女神 链接&#xff1a;文心智能体平台AgentBuilder | 想象即现实 (baidu.com)https://agents.baidu.com/agent/preview/RulbsUjIGj4wsinydlBH7AR3NQKFungt 简介 “你的微信女神”是一个直率的智能体&#xff0c;她用犀利而真实的言辞帮助用户…

kubernetes调度2

1、各种缩写的应用 [rootk8s-master test]# kubectl get rsNAME DESIRED CURRENT READY AGEtest001-64c7957b5c 2 2 2 8m59stest001-698b98bb8f 0 0 0 12m[rootk8s-master test]# kubectl get replicas…

医疗领域患者监控中的手势识别:一种深度卷积神经网络方法

这篇论文的标题是《Hand Gesture Recognition for Patient Monitoring in the Medical Field: A Deep Convolution Neural Networks Approach》&#xff0c;作者们来自印度的Chaitanya Bharathi Institute of Technology电子与通信工程系。论文主要探讨了在医疗领域&#xff0c…

【Redis入门到精通二】Redis核心数据类型(String,Hash)详解

目录 Redis数据类型 1.String类型 &#xff08;1&#xff09;常见命令 &#xff08;2&#xff09;内部编码 2.Hash类型 &#xff08;1&#xff09;常见命令 &#xff08;2&#xff09;内部编码 Redis数据类型 查阅Redis官方文档可知&#xff0c;Redis提供给用户的核心数据…

先导小型五轴数控加工中心助力职业教育

职业本科高校规模不断扩大&#xff0c;职校学生升学渠道打通&#xff0c;产教融合更加紧密&#xff0c;科教融汇成果不断出现&#xff0c;教学改革持续深化……种种迹象表明&#xff0c;职业教育大变革已经开启。 推进新型工业化、发展新质生产力等时代命题与职业教育发展方向和…

深刻理解OS管理与进程

OS是什么 OS&#xff1a;operator system OS的本质是进行软硬件资源管理的软件 内存是cpu与外部间的巨大缓存 OS的意义 对下&#xff1a;操作系统对下软硬件资源的管理&#xff0c;保证系统稳定的&#xff0c;高效的安全的能进行良好的工作&#xff08;手段&#xff09;对上&am…

Linux--禁止root用户通过ssh直接登录

原文网址&#xff1a;Linux--禁止root用户通过ssh直接登录_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Linux服务器怎样禁止root用户通过ssh直接登录。 为什么要禁止&#xff1f; 因为root用户是每个Linux系统都有的&#xff0c;黑客可以使用root用户名尝试不同的密码来暴力破…

电机控制系统PCB设计 222

6 还能只用网络标号?没用网络端口比较电流 通过SD引脚来控制电机驱动右边是电机四个MOS管是连在一起的不懂为啥加左边这个好像说只要用芯片的 就加个滤波电容?DRV87里也有这个 难道都要有这个?? 缓冲? 数字逻辑?加了左上这个 吸收的防止电源超过7.2V这放旁边就行??? 取…

C++ OpenCV Canny边缘检测,使用Trackbar滑动条选择最佳参数

目录 一、代码二、检测效果 一、代码 下面代码可以通过Trackbar滑动条拖动查看最佳阈值&#xff0c;使用只需要修改导入图像路径。本教程提供的边缘检测方法为Canny&#xff0c;学者可以在此框架基础上替换为其它检测方法。 具体代码见下&#xff1a; #include <iostream…

重磅发布:OpenAI o1全新推理模型系列

2024年9月12日&#xff0c;OpenAI正式推出全新的推理模型系列——OpenAI o1。这款全新AI模型系列专为解决复杂问题而设计&#xff0c;能够在响应前花费更多时间进行思考&#xff0c;并通过深入推理应对比以往模型更具挑战性的科学、编程和数学问题。 1. 开发背景与首发版本 今…

【记录】C++学习路线

一、记录心得&#xff1a; 目前自己的状况是刚上大三&#xff0c;学校是双非一本&#xff0c;教的主流方向是 J A V A JAVA JAVA开发方向&#xff0c;还有就是嵌入式方向&#xff0c;这两个方向自己都不是很感兴趣&#xff0c;所以从大一开始就自学 C C C&#xff0c;加入 A…

2024.9.20 作业

写一个shell脚本&#xff0c;将以下内容放到脚本中&#xff1a; a.在家目录下创建目录文件&#xff0c;dir b.dir下创建dir1和dir2 c.把当前目录下的所有文件拷贝到dir1中&#xff0c; d.把当前目录下的所有脚本文件拷贝到dir2中 e.把dir2打包并压缩为dir2.tar.xz f.再把…

Cypress初次安装启动常见问题

安装成功后会出现如图所示目录和文件 Cypress启动问题 进入node_modules下的.bin 目录,执行命令: cypress open 启动cypress&#xff0c;此时会有一个报错&#xff0c;如图 需要进入项目目录&#xff0c;编辑package.json文件中scripts配置 此时再次启动CMD&#xff0c;进入根…

CSP-J2024全真模拟题 阅读程序题3+程序填空题

由于明天考试&#xff0c;今天晚上给大家提供详细的答案和解析&#xff0c;求关注点赞和评论 28.将第 1 行改为 &#xff03;include<iostream>&#xff0c;程序的运行结果不变。&#xff08;&#xff09; A.对B.错 29.本程序用到了队列而不是栈的思想。&#xff08;&a…

pdb文件查看工具pdbripper.exe

下载地址:https://www.bing.com/ck/a?!&&p249322afbfbc575bJmltdHM9MTcyMTM0NzIwMCZpZ3VpZD0yMjBkODE2MC1hYjNhLTZkYTMtMGVlYi05NWQ5YWE3OTZjOGEmaW5zaWQ9NTE4Mg&ptn3&ver2&hsh3&fclid220d8160-ab3a-6da3-0eeb-95d9aa796c8a&psqpdbripper.exe&…

交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面

一、介绍 交通标志识别系统。本系统使用Python作为主要编程语言&#xff0c;在交通标志图像识别功能实现中&#xff0c;基于TensorFlow搭建卷积神经网络算法模型&#xff0c;通过对收集到的58种常见的交通标志图像作为数据集&#xff0c;进行迭代训练最后得到一个识别精度较高…

多态的使用和原理(c++详解)

一、多态的概念 多态顾名思义就是多种形态&#xff0c;它分为编译时的多态&#xff08;静态多态&#xff09;和运行时的多态&#xff08;动态多态&#xff09;&#xff0c;编译时多态&#xff08;静态多态&#xff09;就是函数重载&#xff0c;模板等&#xff0c;通过不同的参数…

Netty源码解析-请求处理与多路复用

摘要 Netty源码系列-NioEventLoop 1.1 Netty给Channel分配Nio Event Loop的规则 看下图&#xff0c;EventLoopGroup是线程组&#xff0c;每个EventLoop是一个线程&#xff0c;那么线程处理请求是怎么分配的呢&#xff1f;我们看一下源码 1.1.1 MultithreadEventLoopGroup.…

人力资源数据集分析(二)_随机森林与逻辑回归

数据入口&#xff1a;人力资源分析数据集 - Heywhale.com 数据说明 字段说明EmpID唯一的员工IDAge年龄AgeGroup年龄组Attrition是否离职BusinessTravel出差&#xff1a;很少、频繁、不出差DailyRate日薪Department任职部门&#xff1a;研发部门、销售部门、人力资源部门Dista…