C++学习——函数调用运算符、function类模板

2023-11-13

一、函数调用运算符

1、圆括号()就是函数调用的明显标记,()有一个称呼叫做“函数调用运算符”;

2、如果我在类中重载了函数调用运算符,那么我们就可以像使用函数一样使用该类的对象了。对象(实参):

class BiggerThanZero
{
public:
    //重载圆括号(函数调用运算符)
    int operator()(int value) const
    {
    	if (value < 0)
    		return 0;
    	return value;
    }
};

int main()
{
    int i = 200;
    BiggerThanZero obj;
    int result = obj(i);//等价于obj.operator()(i);
    //int result = obj.operator()(i);
    cout << result << endl;
    return 0;
}

2、对象(实参)有点似曾相识,那就是有参构造函数:

class BiggerThanZero
{
public:
    //重载圆括号(函数调用运算符)
    BiggerThanZero(int i){};//有参构造函数
    int operator()(int value) const
    {
    	if (value < 0)
    		return 0;
    	return value;
    }
};

int main()
{
    int i = 200;
    BiggerThanZero obj(i);//这是对象定义并初始化,所以调用的是构造函数,并没有调用重载的()
    int result = obj(i);//等价于obj.operator()(i);
    //int result = obj.operator()(i);
    cout << result << endl;
    return 0;
}

3、结论:

      1)只要这个对象所属的类重载了()(函数调用运算符),那么这个类对象就变成了可调用的勒,而且可以调用多个版本的(),只要在参数类型或者数量上有差别即可;

class BiggerThanZero
{
public:
    //重载圆括号(函数调用运算符)
    BiggerThanZero(int i){};//有参构造函数
    int operator()(int value) const //重载() 1
    {
    	if (value < 0)
    		return 0;
    	return value;
    }
    int operator()(int value, char c) const//重载() 2
    {
    	if (value < 0)
    		return 0;
    	return value;
    }
    int operator()(int value, char c, int value1) const//重载() 3
    {
    	if (c < 0)
    		return 0;
    	return c;
    }
};

      2)这个类重载了(),那么该类的对象就多了个新名字,叫“函数对象”,因为可以调用这种对象。或者换一种说法:这些对象的行为像函数一样;

4、不同调用对象的相同调用形式(如下echoValue函数与BiggerThanZero类中的operator()就叫做调用形式相同):

class BiggerThanZero
{
public:
    int operator=(int value) const
    {
    	cout << "class value : " << value << endl;
    	if(value < 0)
    		return 0;
    	return value;
    }
};

int echoValue(int value)//调用参数和返回值与BiggerThanZero类中的operator()成员相同
{
    cout << "echoValue : " << value << endl;
    if(value < 0)
    	return 0;
    return value;
}

      1)函数echoValue和类BiggerThanZero的重载(),这两个东西的调用参数和返回值相同,我们可以称之为“调用形式相同”;
      2)一种调用形式对应一个函数类型,如int(int) 表示接受一个int参数和返回一个int值;
  5、可调用对象
      1)如下两种实现都是可调用对象:
             a)echoValue函数;
             b)重载了函数调用运算符的BiggerThanZero类对象;

      2)把这些可调用对象的指针保存起来,目的是方便我们随时调用这些“可调用对象”,这些指针感觉像我们C语言中的函数指针;

int (*p)(int x);//p就是定义的指针变量
p = max;//函数max的入口地址给p
int result = p(5);//调用函数max 等价于 max(5);

三、标准库map类型介绍

1、map是一个类模板,头文件#include <map>;

2、Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。

3、map是一类关联式容器。它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。

对于迭代器来说,可以修改实值,而不能修改key。

4、用法:

map<int, string> mapStudent;

5、数据的插入:

      1)用insert函数插入pair数据

//数据的插入--第一种:用insert函数插入pair数据  
#include <map>  
#include <string>   
#include <iostream>    
using namespace std;  
      
int main()      
{  
    map<int, string> mapStudent;  

    mapStudent.insert(pair<int, string>(1, "student_one"));  
    mapStudent.insert(pair<int, string>(2, "student_two"));  
    mapStudent.insert(pair<int, string>(3, "student_three"));  
    map<int, string>::iterator iter;  
      
    for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
        cout<<iter->first<<' '<<iter->second<<endl;  
    return 0;
}  

      2)用insert函数插入value_type数据:

//第二种:用insert函数插入value_type数据,下面举例说明      
#include <map>  
#include <string>  
#include <iostream>  
using namespace std;  
      
int main()  
{  
    map<int, string> mapStudent;  
    
    mapStudent.insert(map<int, string>::value_type (1, "student_one"));  
    mapStudent.insert(map<int, string>::value_type (2, "student_two"));  
    mapStudent.insert(map<int, string>::value_type (3, "student_three"));  
    map<int, string>::iterator iter;  
    for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
        cout<<iter->first<<' '<<iter->second<<endl;  
    return 0;     
}  

      3)用数组方式插入数据:

//第三种:用数组方式插入数据,下面举例说明
#include <map>
#include <string>
#include <iostream>
using namespace std;
 
int main()
{
    map<int, string> mapStudent;
 
    mapStudent[1] = "student_one";
    mapStudent[2] = "student_two"; 
    mapStudent[3] = "student_three";

    map<int, string>::iterator iter; 
    for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
        cout<<iter->first<<' '<<iter->second<<endl;
    return 0;
}

6、注意:以上三种用法,虽然都可以实现数据的插入,但是它们是有区别的,当然了第一种和第二种在效果上是完成一样的,用insert函数插入数据,在数据的 插入上涉及到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是插入数据不了的,但是用数组方式就不同了,它可以覆盖以前该关键字对 应的值;

7、参考博客:C++ STL 中 map 容器的说明和使用技巧

四、标准库function类型介绍

1、function是一个类模板,头文件#include <functional>;

2、function类模板,要提供模板参数来表示该function类型能够表示的“对象的调用形式”,类模板std :: function是一个通用的多态函数包装器, std :: function的实例可以存储,复制和调用任何可调用的目标 :包括函数,lambda表达式,绑定表达式或其他函数对象,以及指向成员函数和指向数据成员的指针。当std::function对象未包裹任何实际的可调用元素,调用该std::function对象将抛出std::bad_function_call异常;

template< class R, class... Args >
class function<R(Args...)>;
模板参数说明:
    R: 被调用函数的返回类型
    Args…:被调用函数的形参

function<int(int)>//声明了一个function()类型,用来代表一个可调用对象,它所代表的这个可调 
                  //用对象是:接受一个int参数,返回一个int类型;

五、可调用对象的使用

class BiggerThanZero
{
public:
    int operator=(int value) const
    {
    	cout << "class value : " << value << endl;
    	if(value < 0)
    		return 0;
    	return value;
    }
};

int echoValue(int value)//调用参数和返回值与BiggerThanZero类中的operator()成员相同
{
    cout << "echoValue : " << value << endl;
    if(value < 0)
    	return 0;
    return value;
}

int main()
{
    map<string, function<int(int)>> myoper = {
        {"a1", echoValue},
        {"a2", obj},
        {"a3", BiggerThanZero}
    };

    myoper["a1"](12);//调用echoValue函数
    myoper["a2"](13);//调用obj对象的operator()函数
    myoper["a3"](14);//调用BiggerThanZero类重载()函数
    
    return 0;
}

1、一旦function遇到echoValue的重载版本就无法识别,编译不通过;

int echoValue(int value)//调用参数和返回值与BiggerThanZero类中的operator()成员相同
{
    cout << "echoValue : " << value << endl;
    if(value < 0)
    	return 0;
    return value;
}

int echoValue()
{
    return 1;
}

int main()
{
    map<string, function<int(int)>> myoper = {
        {"a1", echoValue};//编译报错
    };
    
    return 0;
}

      解决:我们可以通过定义函数指针类解决,如下:

int (*fp)(int) = echoValue;
int (*fp1)() = echoValue;

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++学习——函数调用运算符、function类模板 的相关文章

  • 完成端口(CompletionPort)详解 - 手把手教你玩转网络编程系列之三

    http blog csdn net xujiezhige article details 41115453
  • 5G时代的应用场景及商业模式和财富商机

    原创文章 转载请与作者联系 0 前言 互联网兴起 诞生了一批富翁 如马云 马化腾 移动互联网兴起后 3G时代 有人做电商发财了 4G时代 有人写公众号月入六位数 有人主播卖货日进斗金 有人靠着短视频实现了财务自由 5G将开启充满机会的时代
  • Hadoop的安装(单机、伪分布、完全分布)

    安装单机模式 1 设置Hadoop配置文件 进入Hadoop配置文件所在目录 修改hadoop env sh文件 2 测试Hadoop 创建输入文件 input 在data txt中写下内容 运行Mapreduce WordCount例子
  • USB接口针式打印机

    1 针式打印机原理 针式打印机16针是纵向排列 每次打印垂直的16bit 然后右移一bit 继续下列打印 字节的MSB表示最上面的点 字节LSB表示最下面的点 由于汉字字模的点阵是横向排列的 而提供给打印头的信息却需要按纵向排列 所以必须再
  • 合并两个链表

    输入两个单调递增的链表 输出两个链表合成后的链表 当然我们需要合成后的链表满足单调不减规则 public class Solution public ListNode Merge ListNode list1 ListNode list2
  • IDEA创建Javaweb项目之方法3之使用JavaEnterprise

    目录 1 file project enterprise 2 结构如下 3 配置Tomcat服务器 4 重要部署不要忘记 ps idea中别配置错Tomcat 1 file project enterprise 无脑默认即可 2 结构如下
  • Linux命令_netstat & 接口、端口、路由统计

    简介 netstat用于打印网络连接 路由表 接口统计信息 伪装连接和多播成员关系 netstat打印关于Linux网络子系统的信息 打印信息的类型由第一个参数控制 语法 netstat veenNcCF
  • maven打成jar包

    还是实践出真知啊
  • 算法题目练习(C/c++/java)

    记录做过的经典题型 以便于以后查看 目录 二分法 1 二分查找一个数 2 二分查找左边界 3 二分查找右边界 计算最大公约数 辗转相除 递归辗转 链表的逆置 前缀和求法 一维前缀和 二维前缀和 包子凑数 扩展欧几里得算法 例子 青蛙的约会
  • 【全民编程】《软件编程-讲课视频》【零基础入门到实战应用】

    第一阶段 零基础编程到入门 视频讲解 第二阶段 工作实操指导
  • EC变色玻璃介绍

    EC Electrochromic 全称电致变色 最外层的两层EC器件基底将所有材料包裹起来 EC器件基底大部分为玻璃 变色玻璃组成 EC变色的本质是在电压作用下材料的光学性质 透过率 反射率 吸收率等 发生稳定 可逆的变化 在EC薄膜两边
  • VMM基础

    复杂度3 5 机密度3 5 最后更新2021 04 20 VMM Virtual Memory Management是所有操作系统都要解决的问题 也是非常硬件相关的问题 必须从硬件CPU的地址管理开始谈起 我们先了解一些术语 Page 内存
  • Sklearn——5折交叉验证评估模型性能

    学习资料 sklearn 中文文档 http www scikitlearn com cn pandas cookbook https github com iamseancheney pythonbooks blob master Pan
  • NLP-分词器:SentencePiece【参考Chinese-LLaMA-Alpaca在通用中文语料上训练的20K中文词表并与原版LLaMA模型的32K词表进行合并的代码】

    背景 随着ChatGPT迅速出圈 最近几个月开源的大模型也是遍地开花 目前 开源的大语言模型主要有三大类 ChatGLM衍生的大模型 wenda ChatSQL等 LLaMA衍生的大模型 Alpaca Vicuna BELLE Phoeni
  • 业内首发

    区块链数据服务 Blockchain Data Service BDS 是京东云区块链产品部发推出的 其将区块链的链式 非结构化数据通过技术手段进行结构化存储 实时同步到高性能数据仓库中 用户可以通过区块链数据查询工具 实现简单的条件查询和
  • springboot+rabbitmq两小时入门(七):生产者发送失败和消费者消费失败处理

    消息队列经常会发送失败和消费失败 这两种问题在日常工作中是不可忽视的 消息发送失败情况 1 网络抖动导致生产者和mq之间的连接中断 导致消息都没发 答 rabbitmq有自动重连机制 叫retry 具体到rabbitTemplate中叫re
  • LVS——DR模式下的健康检查(ldirectord)

    对后端服务器健康检查 如果一个后端服务器挂掉将这个服务器踢出集群 让用户无感知 否则会出现访问时好时坏的情况 当宕机的服务器恢复正常时自动将他加回集群 当服务器集群宕机的时候返回一个统一的错误页面 这个页面来自于调度器 注意 ldirect
  • linux 下搭建BugFree

    遇到问题 公司项目组开发小组需要搭建缺陷管理系统 方便开发小组提交Bug 介绍 BugFree基于PHP和MySQL开发 是免费且开放源代码的缺陷管理系统 服务器端在Linux和Windows平台上都可以运行 客户端无需安装任何软件 通过I
  • [运维] 在debian系统下安装KODExplorer(可道云)

    系统环境说明 系统 Debian GNU Linux 10 buster 平台 amd64 参考文献 KODExplorer 系统环境软件安装 KODExplorer 运行环境软件安装 sudo apt install php php cu
  • python线程池 ThreadPoolExecutor 使用详解

    从 Python3 2 开始 标准库为我们提供了 concurrent futures 模块 它提供了 ThreadPoolExecutor 和 ProcessPoolExecutor两个类 实现了对 threading 和 multipr

随机推荐

  • [ACTF2020]exec

    ACTF2020 exec 点开进入题目 可以看见一个ping 首先第一反应是输入自己电脑的地址 可以得到 然后凭感觉进行 输入127 0 0 1 whoami 因为linux的默认用户组是www data 因此这是linux 继续下去 遍
  • Flash地址空间的数据读取——STM32

    目录 一 STM32 的内部 FLASH 简介 二 工程验证 三 总结 参考链接 一 STM32 的内部 FLASH 简介 在 STM32 芯片内部有一个 FLASH 存储器 它主要用于存储代码 我们在电脑上编写好应用程序后 使用下载器把编
  • Linux学习笔记——Linux实用操作(二)

    04 Linux实用操作 4 6 IP地址 主机名 4 6 1 IP地址 主机名 学习目标 掌握什么是IP地址 掌握什么是主机名 掌握什么是域名解析 4 6 1 1 IP地址 1 每一台联网的电脑都会有一个地址 用于和其它计算机进行通讯 I
  • Qt界面之间信息传递(自身项目经验,一文必懂)

    Qt最常用的就是信号与槽这一结构 对于这一结构 我们可以看下Qt4和Qt5以上版本的差别 connect ui gt QCP fabric edit SIGNAL mousePress QMouseEvent this SLOT myMou
  • NVIDIA驱动安装及报错处理

    NVIDIA驱动安装及报错处理 下载GPU驱动包 安装GPU驱动包 卸载GPU驱动包 GPU驱动包安装排错 下载GPU驱动包 驱动下载 https www nvidia com Download Find aspx 复制好地址后 使用wge
  • order函数的简单使用

    a lt c 5 4 3 2 1 b lt c 1 2 3 4 5 c lt cbind a b c order c 1 按第一列递增排序 转载https blog csdn net illfm article details 152183
  • Hinton开源CapsuleNet

    当前的深度学习理论是由Geoffrey Hinton大神在2007年确立起来的 但是如今他却认为 CNN的特征提取层与次抽样层交叉存取 将相同类型的相邻特征检测器的输出汇集到一起 是大有问题的 去年9月 在多伦多接受媒体采访时 Hinton
  • Restful定义,接口设计原则及优点

    1 什么是REST REST全称是Representational State Transfer 中文意思是表述 编者注 通常译为表征 性状态转移 它首次出现在2000年Roy Fielding的博士论文中 Roy Fielding是HTT
  • JVM各垃圾回收器优缺点及应用场景

    目录 为什么需要使用垃圾收集器 JVM各垃圾收集器特点 1 Serial收集器 2 ParNew收集器 3 Parallel Scavenge收集器 4 Serial Old收集器 5 Parallel Old收集器 6 Serial Se
  • 华为OD机试真题- 红黑图

    题目描述 众所周知红黑树是一种平衡树 它最突出的特性就是不能有两个相邻的红色节点 那我们定义一个红黑图 也就是一张无向图中 每个节点可能有红黑两种颜色 但我们必须保证没有两个相邻的红色节点 现在给出一张未染色的图 只能染红黑两色 问总共有多
  • js实现字符串排序

    规则 规则 1 英文字母从 A 到 Z 排列 不区分大小写 如 输入 Type 输出 epTy 规则 2 同一个英文字母的大小写同时存在时 按照输入顺序排列 如 输入 BabA 输出 aABb 规则 3 非英文字母的其它字符保持原来的位置
  • 29.Kubernetes(十一)-----监控(helm可视化 web图形)

    helm可视化 web图形 一 镜像 1 下载镜像 2 上传镜像到仓库 二 编写配置文件 三 安装部署 1 真机解析 2 添加用户 赋予管理权限 3 真机访问 4 访问成功 5 Token登陆 四 图形操作 1 添加仓库 编写仓库解析 添加
  • 嵌入式单片机及其相关博客及教程

    一 单片机 1 嵌入式单片机程序架构之时间片轮询法 https mp weixin qq com s F6FGDwW Rqaxzf9BYcg6yQ 2 stm32 f429 移植 littlevGL https mp weixin qq c
  • 芯片设计中的latch_闩锁效应(Latch-up)详解

    在CMOS集成电路中 闩锁效应不容忽视 这篇文章将从0开始给大家介绍闩锁效应 Latch up 以及有效抑制闩锁效应的方法 一 背景知识 1 双极结型晶体管 Bipolar Junction Transistor BJT 图1 NPN型BJ
  • 四、数据库与身份认证

    目录 安装与配置MySQL MySQL的基本使用 使用 MySQL Workbench 管理数据库 1 连接数据库 2 了解主界面的组成部分 3 创建数据库 4 创建数据表 5 向表中写入数据 SQL 的 SELECT 语句 1 语法 2
  • 视频的容器与格式

    转发自 http blog csdn net tttyd article details 6893392 1 视频容器格式简介 一般而言 视频文件的扩展名就是视频的容器名 比如 avi文件 或者 mp4文件 avi和mp4只是容器格式 好比
  • 五大开源Web服务器

    开源产品的出现不仅获得了个人用户的喜爱 众多知名企业也青睐于它 虽然开源产品数不胜数 但并不是每一个开源产品都能被广泛应用并得到大众的好评 在众多成功的开源产品中 只有少数领头羊 而其它产品只能望其项背 本文汇总了五款开源Web服务器 来看
  • STM32F103 实验 输入捕获

    目录 本文 在上一章的基础上 将介绍如下内容 输入捕获 上一篇 STM32F103 实验 PWM输出 https blog csdn net qq 40318498 article details 96475438 参考 STM32F103
  • 测试——自动化测试(Selenium工具)

    目录 一 自动化测试的概念以及分类 二 Selenium web自动化测试工具 1 自动化测试的一些前置工作 2 第一个自动化实例 3 总结 编辑 三 Selenium常用方法 定位元素的方法 元素的操作 等待 强制等待 待补充 隐式等待
  • C++学习——函数调用运算符、function类模板

    一 函数调用运算符 1 圆括号 就是函数调用的明显标记 有一个称呼叫做 函数调用运算符 2 如果我在类中重载了函数调用运算符 那么我们就可以像使用函数一样使用该类的对象了 对象 实参 class BiggerThanZero public