c++杂谈-5

news2024/12/26 21:37:35

目录

      • 一、一些c++11新特性
        • 1. decltype关键字及函数后置返回类型
        • 2. 函数后置返回类型
      • 二、c++的内存模型
      • 三、函数指针和回调函数
      • 四、函数模版的注意事项


一、一些c++11新特性

1. decltype关键字及函数后置返回类型

在C++11中,decltype操作符,用于查询表达式的数据类型

语法:decltype(expression)var;

decltype只分析表达式并得到它的类型,不会计算执行表达式。decltype分析函数也只是一种表达式,因此不必担心在使用decltype时调用了函数。

decltype的类型推导规则:

  1. 如果expression是一个没有用括号括起来的标识符,则var的类型与该标识符的类型相同,包括const等限定符。
  2. 如果expression是一个函数调用,则var的类型与函数的返回值类型相同(函数不能返回void,但可以返回void*)。
  3. 如果expression是一个左值(能取地址)、或者用括号括起来的标识符,那么var的类型是expression的引用。
  4. 如果上面的条件都不满足,则var的类型与expression的类型相同。

decltype可以结合typedef和using定义别名使用。

int func(){
...
}

short a = 5;
const* char b = "abc";
short& c = a;
short d = 3;

decltype(a) da; // da为变量的类型:short
decltype(b) db; // db为变量的类型:const* char
decltype(c)dc = d; // dc为引用类型:short&

decltype(func())dd = d; // dd为函数返回值类型:int
decltype(func)* de = func; // de为函数指针类型:int (*func)
de(); // 调用函数

decltype(++a)df; // df为左值引用类型:short &a
decltype((a))dg; // dg为引用类型:short &a

decltype(func)dh; // dh为func函数的类型:int func()
decltype((func))di; // di为func函数的引用:int (&di)()

decltype(func())dj; // auto e = func(); 这里dj和e都为int类型,但decltype不执行函数调用,而auto要求执行函数调用得到返回值(这样才能推导)。

使用auto的案例:

#include <iostream>

using namespace std;

template<typename T1, typename T2>
void func(T1 x, T2 y) {
	auto tmp = x + y; // 使用auto关键字来解决泛化参数的混合类型运算结果的类型问题
	cout << "tmp=" << tmp << endl;
}

int main(int argc, const char **argv) {
	short a = 5;
	char b = 3;
	func(a, b);

	return 0;
}

2. 函数后置返回类型

int func(int x,double y);

等同于:

auto func(int x,double y)-> int;

将返回类型移到了函数声明的后面。
auto是一个占位符(C++11给auto新增的角色),为函数返回值占了一个位置。
这种语法也可以用于函数定义:

auto func(int x, double y)->int {
	// 函数体。
}

整合decltype的案例:

#include <iostream>

using namespace std;

template<typename T1, typename T2>
auto func(T1 x, T2 y) -> decltype(x+y) {
	decltype(x+y) tmp = x + y;
	return tmp;
}

int main(int argc, const char **argv) {
	cout << "tmp=" << func(3.14, 5) << endl;

	return 0;
}

C++14标准对函数返回类型推导规则做了优化,函数的返回值可以用auto,不必尾随返回类型。

#include <iostream>

using namespace std;

template<typename T1, typename T2>
auto func(T1 x, T2 y) {
	decltype(x+y) tmp = x + y;
	// auto tmp = x + y; 也可以
	return tmp;
}

int main(int argc, const char **argv) {
	cout << "tmp=" << func(3.14, 5) << endl;

	return 0;
}

二、c++的内存模型

在这里插入图片描述
栈和堆的主要区别:

  1. 管理方式不同:栈是系统自动管理的,在出作用域时,将自动被释放;堆需手动释放,若程序中不释放,程序结束时由操作系统回收。
  2. 空间大小不同:堆内存的大小受限于物理内存空间;而栈就小得可怜,一般只有8M(可以修改系统参数)。
  3. 是否产生碎片:对于栈来说,进栈和出栈都有严格的顺序(先进后出),不会产生碎片;而堆频繁地分配和释放,会造成内存空间的不连续,容易产生碎片,太多的碎片会导致性能的下降。

三、函数指针和回调函数

函数指针的主要用途就是回调函数。
函数的类型是指:返回值和参数列表(函数名和形参名不是)——形参只涉及个数与类型

int (*pfa)(int, string);
bool (*pfb)(int, string);

基本示例

#include <iostream>

using namespace std;

void func(int no, string str) {
	cout << "NO. " << str << endl;
}

int main(int argc, const char **argv) {
	int no = 3;
	string msg = "balabala...";

	void (*pfunc)(int, string); // 声明函数指针
	pfunc = func;
	pfunc(no, msg); // 用函数指针调用函数:c++方式
	(*pfunc)(no, msg); //  用函数指针调用函数:c方式

	return 0;
}

回调函数:函数由用户定义,但调用不由用户来完成,调用随后交给系统/框架去完成。

#include <iostream>

using namespace std;

void custome1() {
	cout << "custome1" << endl;
}

void custome2(string msg) {
	cout << "custome2: " << msg << endl;
}

void custome3(string msg) {
	cout << "custome3: " << msg << endl;
}

void framework(void (*callback)()) {
	cout << "void (*callback)()" << endl;
	callback();
}

void framework(void (*callback)(string)) {
	string msg = "internal";
	cout << "void (*callback)(string): " << msg << endl;
	callback(msg);
}

void framework(void (*callback)(string), string msg) {
	cout << "void (*callback)(string): " << msg << endl;
	callback(msg);
}

int main(int argc, const char **argv) {
	framework(custome1);
	framework(custome2);
	framework(custome3, "external");

	return 0;
}

四、函数模版的注意事项

  1. 可以为类的成员函数创建模板,但不能是虚函数和析构函数。
  2. 使用函数模板时,必须明确数据类型,确保实参与函数模板能匹配上。
swap<int>();
  1. 使用函数模板时,推导的数据类型必须适应函数模板中的代码。
  2. 使用函数模板时,如果是自动类型推导,不会发生隐式类型转换,如果显示指定了函数模板的数据类型,可以隐式类型转换。
template<typename T>
T Add(T a, T b){
	return a+b;
}
...
int a=10;
char b=73;
int c=Add(a,b); //报错:不能进行隐式转换。
int d=Add<int>(a,b); //编译通过:显式指定函数模版的数据类型,可以完成隐式转换。
  1. 函数模板支持多个通用数据类型的参数。
  2. 函数模板支持重载,可以有非通用数据类型的参数。

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

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

相关文章

HarmonyOS NEXT新能力,一站式高效开发HarmonyOS应用

2023年8月6日华为开发者大会2023&#xff08;HDC.Together&#xff09;圆满收官&#xff0c;伴随着HarmonyOS 4的发布&#xff0c;华为向开发者发布了汇聚所有最新开发能力的HarmonyOS NEXT开发者预览版&#xff0c;并分享了围绕“一次开发&#xff0c;多端部署” “可分可合&a…

通过Microsoft Loopback Adapter实现虚拟机和物理机的通信

问题 问&#xff1a;不借助路由器或交换机的情况下&#xff0c;能不能实现主机和虚拟及之间两个软件的通信呢&#xff1f;要求主机和虚拟及均有独立的ip地址&#xff0c;从而进行指定源的组播通信。 答&#xff1a;可以。通过借助虚拟网络适配器&#xff0c;不需要路由器或交…

深度思考rpc框架面经系列之三

6 一个rpc框架的请求调用的流程&#xff08;小红书面试&#xff09; 6.1 讲讲rpc调用原理&#xff0c;比如服务怎么发现&#xff0c;怎么调用&#xff0c;提供者怎么响应。怎么去请求&#xff0c;又怎么回来的 一个RPC&#xff08;远程过程调用&#xff09;框架的核心目的是允…

百度飞浆实战-手写数字识别

目录 参考建模过程1、数据加载和预处理2、模型的网络设计和开发模型组网 3、模型训练 代码实战1、打开aistudio找到项目 参考 视频教程 PaddleAPI DOC 建模过程 1、数据加载和预处理 飞桨框架帮助我们将MNIST数据集进行了内置 数据集名称&#xff1a; MNIST 数据集官网 &am…

2023-08-14 LeetCode每日一题(合并二叉树)

2023-08-14每日一题 一、题目编号 617. 合并二叉树二、题目链接 点击跳转到题目位置 三、题目描述 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xff0c;两棵树上的一些节点将会重叠&#xff08;而另一些不会…

Android布局【RelativeLayout】

文章目录 介绍常见属性根据父容器定位根据兄弟组件定位 通用属性margin 设置组件与父容器的边距padding 设置组件内部元素的边距 项目结构主要代码 介绍 RelativeLayout是一个相对布局&#xff0c;如果不指定对齐位置&#xff0c;都是默认相对于父容器的左上角的开始布局 常见…

3D沉浸式旅游网站开发案例复盘【Three.js】

Plongez dans Lyon网站终于上线了。 我们与 Danka 团队和 Nico Icecream 共同努力&#xff0c;打造了一个令我们特别自豪的流畅的沉浸式网站。 这个网站是专为 ONLYON Tourism 和会议而建&#xff0c;旨在展示里昂最具标志性的活动场所。观看简短的介绍视频后&#xff0c;用户…

[足式机器人]Part5 机械设计 Ch00/01 绪论+机器结构组成与连接 ——【课程笔记】

本文仅供学习使用 本文参考&#xff1a; 《机械设计》 王德伦 马雅丽课件与日常作业可登录网址 http://edu.bell-lab.com/manage/#/login&#xff0c;选择观摩登录&#xff0c;查看2023机械设计2。 机械设计-Ch00Ch01——绪论机器结构组成与连接 Ch00-绪论0.1 何为机械设计——…

设计HTML5列表和超链接

在网页中&#xff0c;大部分信息都是列表结构&#xff0c;如菜单栏、图文列表、分类导航、新闻列表、栏目列表等。HTML5定义了一套列表标签&#xff0c;通过列表结构实现对网页信息的合理排版。另外&#xff0c;网页中还包含大量超链接&#xff0c;通过它实现网页、位置的跳转&…

ChatGPT爆火,会给教育带来什么样的影响或者冲击?

近来&#xff0c;人工智能聊天机器人ChatGPT连上热搜&#xff0c;火爆全网。ChatGPT拥有强大的信息整合能力、自然语言处理能力&#xff0c;可谓是“上知天文&#xff0c;下知地理”&#xff0c;而且还能根据要求进行聊天、撰写文章等。 ChatGPT一经推出&#xff0c;便迅速在社…

C语言——动态内存函数(malloc、calloc、realloc、free)

了解动态内存函数 前言&#xff1a;一、malloc函数二、calloc函数三、realloc函数四、free函数 前言&#xff1a; 在C语言中&#xff0c;动态内存函数是块重要的知识点。以往&#xff0c;我们开辟空间都是固定得&#xff0c;数组编译结束后就不能继续给它开辟空间了&#xff0…

机器学习:基本介绍

机器学习介绍 Hnad-crafted rules Hand-crafted rules&#xff0c;叫做人设定的规则。那假设今天要设计一个机器人&#xff0c;可以帮忙打开或关掉音乐&#xff0c;那做法可能是这样&#xff1a; 设立一条规则&#xff0c;就是写一段程序。如果输入的句子里面看到**“turn of…

maven工具-maven的使用-镜像仓库、本地仓、IDEA使用maven

Maven 一、为什么使用maven 添加第三方jar包jar包之间的依赖关系处理jar包之间的冲突获取第三方jar包将项目拆分成多个工程模块实现项目的分布式部署 二、maven简介 ​ Maven项目对象模型(POM)&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的…

B树和B+树区别

B树和B树的区别 B树 B树被称为平衡树&#xff0c;在B树中&#xff0c;一个节点可以有两个以上的子节点。B树的高度为log M N。在B树中&#xff0c;数据按照特定的顺序排序&#xff0c;最小值在左侧&#xff0c;最大值在右侧。 B树是一种平衡的多分树&#xff0c;通常我们说m阶…

Base64编码-算法特别的理解

Base64 在DES加密和AES加密的过程中&#xff0c;加密的编码会出现负数&#xff0c;在ascii码表中找不到对应的字符&#xff0c;就会出现乱码。为了解决乱码的问题&#xff0c;一般结合base64使用 所谓Base64&#xff0c;即是说在编码过程中使用了64种字符&#xff1a;大写A到Z、…

【多线程】网络原理初识

网络原理初识 1. 网络发展史1.2 独立模式1.3 网络互联1.3 局域网1.4 广域网 2. 网络通信基础2.1 IP地址2.2 端口号2.3 认识协议2.4 五元组2.5 协议分层2.5.1 什么是协议分层2.5.2 协议分层的好处2.5.2 OSI七层模型2.5.3 TCP/IP五层模型 2.6 封装和分用2.6.1 封装2.6.1.1 应用层…

MyBatis-Plugin源码全面分析

三、MyBatis-Plugin 1. 基本开发方式 需求&#xff1a;在MyBatis执行之前打印一行醒目的日志&#xff0c;携带参数 实现Interceptor接口&#xff1a; Intercepts(Signature(type Executor.class,method "query",args {MappedStatement.class,Object.class, RowB…

在 Linux 中使用 cp 命令

cp 命令是 Linux 中一个重要的命令&#xff0c;你可能经常会用到它。 正如名称所示&#xff0c;cp 代表 复制copy&#xff0c;它被用于 在 Linux 命令行中复制文件和目录。 这是一个相对简单的命令&#xff0c;只有几个选项&#xff0c;但你仍有必要深入了解它。 在展示 cp …

UML图绘制 -- 类图

1.类图的画法 类 整体是个矩形&#xff0c;第一层类名&#xff0c;第二层属性&#xff0c;第三层方法。 &#xff1a;public- : private# : protected空格: 默认的default 对应的类写法。 public class Student {public String name;public Integer age;protected I…

ardupilot参数的mavlink实现

专业名词释义&#xff0c;参数缩写 gimbal 云台&#xff0c;万向接头 failsafe 故障保护 Collective&#xff1a; 总距 Swashplate &#xff1a; 倾斜盘 SW&#xff1a; Swashplate 倾斜盘 RSC&#xff1a; Rotor Speed Control RC&#xff1a; Radio Channel 无线通道 DDFP&am…