从0开始的数据结构速过——番外(1)

目录

尝试

思考与架构设置

编写!

一些额外知识的补充

可变参数模板

std::common_type

std::forward


这是《数据结构从0开始》的一个番外。实际上是介绍一下一些现代C++的写法。这里以快速构建std::array作为契机来说明一下一些现代C++的语法。

尝试

我们在这里呢,需要完成一个比较底层的工作:那就是为任何type的array构造一个方便的函数。他接受任意长度的参数,然后返回这些参数组成的array,就是这样的简单!

想一想,你需要做什么工作呢?

思考与架构设置

显然,我们需要为任何type构建,意味着我们需要使用现代C++的模板来完成这个工作。接受任意长度的参数说明我们需要可变参数模板。std::array还需要一个常量说明长度,意味着我们需要一个编译时推导的长度。

那这样看,至少我们现在需要的是:

  • 可变的参数模板

  • 使用sizeof... (args)来描述我们的参数长度!

编写!

第一步,我们按照函数参数模板的起手来干活,我们需要的是:

#include <array>
#include <type_traits>
​
template<typename ... Args>
auto construct_array(Args&&... args) -> std::array<ATypename, Args_number>{return ...
} 

好吧,还有好多东西并不确定!我们知道,有的时候我们构造数组,需要抽取公共类型。也就是需要使用std::common_type来做这个事情。以及,需要typename强制告知我后面的标识符是一个类型名称而不是一个什么别的东西。因此,ATypename就可以被替代为:

std::common_type<Args...>::type

至于参数的长度,那也就是使用sizeof...(args)表述

#include <array>
#include <type_traits>
​
template<typename ... Args>
auto construct_array(Args&&... args) -> std::array<typename std::common_type<Args...>::type, sizeof...(args)>{using commonType = std::common_type<Args...>::type; // 太长了,rename一下return { std::forward<commonType>(args)... };
}
​

下一步就是具体干活,实现函数体

#include <array>
#include <type_traits>
​
template<typename ... Args>
auto construct_array(Args&&... args) -> std::array<typename std::common_type<Args...>::type, sizeof...(args)>{using commonType = std::common_type<Args...>::type; // 太长了,rename一下return { std::forward<commonType>(args)... };
}

下面我们来试试看:非常的好!

一些额外知识的补充

可变参数模板

C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。

在语义上,可变参数模板和普通模板是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...:

template<typename... Types>

其中,...可接纳的模板参数个数是0个及以上的任意数量,需要注意包括0个。我的另一个意思是,如果需要强迫有N个参数模板,那么:

template<typename T1,typename T2, typename... Types>

很好,现在至少要求两个了。

如果我们关心每一个参数是什么,那么,我们一般会选择递归的处理函数模板,举个例子,我们来递归的调用一个有趣的打印函数printRecursive,他是这样做的:

#include <array>
#include <type_traits>
#include <iostream>
​
void print() {}
​
template<typename PrintableCurrent, typename ... PrintableArgs>
void print(const PrintableCurrent& current, const PrintableArgs&... printableArgs)
{std::cout << current << " ";return print(printableArgs...);
}
​
int main()
{print(1, 2, 3, "hello, world", 'h', 9.1234f);
}

看懂这个代码了吗?我们需要一个终止递归的特化函数,还有一个就是我们的主运行函数。

std::common_type

在C++11标准中引入了common_type,在C++14中引入了common_type_t,它主要是用来获取参数的共有类型的,需要注意的,它获取的类型是退化的,因为它内部调用了std::decay。

#include <iostream>
#include <type_traits>
​
int main() {// 定义几个类型using T1 = int;using T2 = double;
​// 使用 std::common_type 推导出公共类型using CommonType = std::common_type<T1, T2>::type;
​// 输出推导结果std::cout << "The common type of int and double is: ";if constexpr (std::is_same_v<CommonType, double>) {std::cout << "double" << std::endl;} else {std::cout << "unknown type" << std::endl;}
​return 0;
}

std::forward

std::forward 是 C++11 引入的一个函数模板,主要用于完美转发(perfect forwarding)。它的作用是根据传递给它的参数类型(左值或右值)转发给函数参数,而不改变它们的类别(即保留其左值或右值特性)。这对于转发参数到其他函数时非常有用,尤其是在实现泛型函数模板时。

std::forward 通过条件地使用 std::move 来实现对右值的转发,而对于左值,它则简单地返回原值。因此,它通常与 std::move 一起使用,以确保右值不会在不需要的地方被拷贝。

#include <iostream>
#include <utility>
​
void func(int& x) {std::cout << "lvalue func, " << x << std::endl;
}
​
void func(int&& x) {std::cout << "rvalue func, " << x << std::endl;
}
​
template <typename T>
void forward_example(T&& arg) {func(std::forward<T>(arg)); // 完美转发
}
​
int main() {int a = 5;forward_example(a);         // 传递左值forward_example(10);        // 传递右值return 0;
}

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

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

相关文章

Day10_CSS过度动画

Day10_CSS过度动画 背景 : PC和APP项目我们已经开发完毕, 但是再真正开发的时候有些有些简易的动态效果我们可以使用CSS完成 ; 本节课我们来使用CSS完成基础的动画效果 今日学习目标 CSS3过度CSS3平面动态效果CSS3动画效果案例 1. CSS3过渡 ​ 含义 :过渡指的是元素从一种…

如何制作代购系统的客服支持模块

在代购系统中&#xff0c;客服支持模块是维护用户满意度和忠诚度的关键环节。一个有效的客服支持模块不仅可以解决用户的疑问和问题&#xff0c;还可以收集用户反馈&#xff0c;用于改进服务和产品。本文将详细介绍如何制作一个代购系统的客服支持模块&#xff0c;包括前端界面…

【unity小技巧】一些unity3D灯光的使用与渲染及性能优化方案

文章目录 天空盒反射配置太阳耀斑眩光烘培光照烘培光照时弹出错误&#xff0c;记得勾选模型下面的选择阴影项目配置光源模型模型shader的问题 全局光照混合光照模式混合照明模式减性照明模式Shadowmask照明模式间接烘焙照明模式 环境光遮罩灯光探针反射探针技术关闭反射探针可以…

Spring Boot汽车资讯:科技与汽车的对话

5系统详细实现 5.1 管理员模块的实现 5.1.1 用户信息管理 汽车资讯网站的系统管理员可以管理用户&#xff0c;可以对用户信息修改删除审核以及查询操作。具体界面的展示如图5.1所示。 图5.1 用户信息管理界面 5.1.2 汽车品牌管理 系统管理员可以汽车品牌信息进行添加&#xf…

go 学习网站,go例子 go demo go学习视频

1. 代码例子&#xff1a; Go by Example 2. b站 视频&#xff1a; 尚硅谷视频&#xff1a; 004_尚硅谷_程序的基本概念_哔哩哔哩_bilibili 3. go技术文档&#xff1a; fmt Go语言中文文档

记录下,用油猴Tampermonkey监听所有请求,绕过seesion

油猴Tampermonkey监听所有请求&#xff0c;绕过seesion 前因后果脚本编写 前因后果 原因是要白嫖一个网站的接口&#xff0c;这个接口的页面入口被隐藏掉了&#xff0c;不能通过页面调用&#xff0c;幸好之前有想过逆向破解通过账号密码模拟登录后拿到token&#xff0c;请求该…

网络安全:我们的安全防线

在数字化时代&#xff0c;网络安全已成为国家安全、经济发展和社会稳定的重要组成部分。网络安全不仅仅是技术问题&#xff0c;更是一个涉及政治、经济、文化、社会等多个层面的综合性问题。从宏观到微观&#xff0c;网络安全的重要性不言而喻。 宏观层面&#xff1a;国家安全与…

多账号登录管理器(淘宝、京东、拼多多等)

目录 下载安装与运行 解决什么问题 功能说明 目前支持的平台 功能演示 登录后能保持多久 下载安装与运行 下载、安装与运行 语雀 解决什么问题 多个账号的快捷登录与切换 功能说明 支持多个电商平台支持多个账号的登录保持支持快捷切换支持导入导出支持批量删除支持…

浅谈网络 | 二层到三层

目录 物理层到MAC层第一层&#xff08;物理层&#xff09;第二层&#xff08;数据链路层&#xff09;局域网 交换机与VLAN生成树协议VLAN ICMP与pingICMP 协议的格式 网关静态路由是什么&#xff1f; 路由协议如何配置策略路由&#xff1f;动态路由算法动态路由协议 物理层到MA…

c++ 后端

基础知识 1. 指针、引用2. 数组3. 缺省参数4. 函数重载5. 内联函数6. 宏7. auto8. const9. 类和对象10. 类的6个默认成员函数11. 初始化列表12. this指针13. C/C的区别14. C 三大特性15. 结构体内存对齐规则16. explicit17. static18. 友元类、友元函数19. 内部类20. 内存管理&…

汽车资讯新趋势:Spring Boot技术解读

5系统详细实现 5.1 管理员模块的实现 5.1.1 用户信息管理 汽车资讯网站的系统管理员可以管理用户&#xff0c;可以对用户信息修改删除审核以及查询操作。具体界面的展示如图5.1所示。 图5.1 用户信息管理界面 5.1.2 汽车品牌管理 系统管理员可以汽车品牌信息进行添加&#xf…

【C++】vector

一、vector的介绍及使用 1.1 vector的介绍 vector的底层与string相似都是顺序表形式管理数组&#xff0c;本质上来说string就可以归入到vector里面&#xff0c;但是在实际使用中&#xff0c;字符有很多自身独有的接口设计需要&#xff0c;因此string被单独拿出来设计。在前面s…

uniapp Uview上传图片组件Upload会自动刷新

背景 最近在做跑团小程序&#xff0c;马上接近尾声了&#xff0c;今天新增一个团长增加活动页面&#xff1a; 然后一切准备就绪&#xff0c;发现了一个问题&#xff0c;当选择上传图片后&#xff0c;页面会自动刷新&#xff0c;把之前填写的信息全部重置了。奇怪了&#xff0c…

软件测试之缺陷管理

一、软件缺陷的基本概念 1、软件缺陷的基本概念主要分为&#xff1a;缺陷、故障、失效这三种。 &#xff08;1&#xff09;缺陷&#xff08;defect&#xff09;&#xff1a;存在于软件之中的偏差&#xff0c;可被激活&#xff0c;以静态的形式存在于软件内部&#xff0c;相当…

数字资产与大健康领域的知识宝藏:高效知识库搭建策略

在数字化时代&#xff0c;大健康领域的企业积累了丰富的数字资产&#xff0c;这些资产如同一座待挖掘的金矿&#xff0c;蕴含着巨大的价值。高效搭建知识库&#xff0c;能够将这些数字资产转化为企业竞争力。 数字资产与大健康领域知识宝藏 数字资产在大健康领域包括患者数据…

使用WebRTC实现点对点实时音视频通信的技术详解

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用WebRTC实现点对点实时音视频通信的技术详解 使用WebRTC实现点对点实时音视频通信的技术详解 使用WebRTC实现点对点实时音视频…

Leetcode打卡:最少翻转次数使二进制矩阵回文II

执行结果&#xff1a;通过 题目&#xff1a;3240 最少翻转次数使二进制矩阵回文II 给你一个 m x n 的二进制矩阵 grid 。 如果矩阵中一行或者一列从前往后与从后往前读是一样的&#xff0c;那么我们称这一行或者这一列是 回文 的。 你可以将 grid 中任意格子的值 翻转 &…

VTK知识学习(9)-空间变换

1、前言 在三维空间里定义的三维模型&#xff0c;最后显示时都是投影到二维平面&#xff0c;比如在屏幕上显示。 三维到二维的投影包括透视投影&#xff08;Perspective Projection&#xff09;和正交投影&#xff08;Orthogonale Projection&#xff09;。正交投影也叫平行投…

英伟达 Isaac Sim仿真平台安装体验

硬件配置、系统 RTX 3080RAM: 32Gi7-12700Fubuntu20.04 使用Omniverse launcher安装加载isaac sim 这种方法我并没有成功&#xff0c;因为启动的时候报错Failed to create any GPU devices, including an attempt with compatibility mode. 。后面我选择使用 isaac sim dock…

笔记02----重新思考轻量化视觉Transformer中的局部感知CloFormer(即插即用)

1. 基本信息 论文标题: 《Rethinking Local Perception in Lightweight Vision Transformer》中文标题: 《重新思考轻量化视觉Transformer中的局部感知》作者单位: 清华大学发表时间: 2023论文地址: https://arxiv.org/abs/2303.17803代码地址: https://github.com/qhfan/CloF…