当前位置: 首页 > news >正文

C++入门小馆:C++11第三弹(可变参数模板)

嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的
passion。准备好和我一起冲进代码的奇幻宇宙了吗?Let’s go!

请添加图片描述

我的博客:yuanManGan

我的专栏:C++入门小馆 C言雅韵集 数据结构漫游记 闲言碎语小记坊 进阶数据结构 走进Linux的世界 题山采玉 领略算法真谛

在这里插入图片描述


C++ 11



4. 可变参数模板



4.1 基本语法及原理


什么是可变参数呢?

我们的printf函数就是一个可变参数函数,我们可以向prinf函数传入任意数量的参数,并且参数的类型可以不一样。这就是可变参数!

在这里插入图片描述
C++11中支持可变参数模板,也就是支持可变参数的函数模板和类模板,可变数目的参数被称为参数包,存在两种参数包:模板参数包,表示零或多个模板参数;函数参数包:表示零或多个函数参数。

下面是可变参数模板的格式:

template <class ...Args> void Fuc(Args... args){}
template <class ...Args> void Fuc(Args&... args){}
template <class ...Args> void Fuc(Args&&... args){}

sizeof...用来计算参数包的个数。(编译时计算)
在这里插入图片描述


4.2 包扩展


我们可以使用参数包来写可变参数模板,但这不是我们常用的方法。

void ShowList()
{cout << endl;
}
template<class T,class...Args>
void ShowList(T x, Args&& ...args)
{cout << x << " ";ShowList(args...);
}template<class ...Args>
void print(Args&& ...args)
{ShowList(args...);//cout << sizeof...(args) << endl;//sizeof...编译时计算
}

本质是利用了递归。

int main()
{double a = 1.1;print();print(2);print(2,string("ssss"));print(2,string("ssss"), a);return 0;
}

在这里插入图片描述
也可以这样写

template <class T>
int GetArg(const T& x)
{cout << x << " ";return 0;
}template <class ...Args>
void Arguments(Args... args)
{}template <class ...Args>
void Print(Args... args)
{// 注意GetArg必须返回或者到的对象,这样才能组成参数包给Arguments// GetArg的返回值组成实参参数包,传给ArgumentsArguments(GetArg(args)...);cout << endl;
}

在这里插入图片描述
这两种方法了解一下就行了。


4.3 `empalce系列接口


在这里插入图片描述
STL中所有的函数都有一个emplace版本

它们都说emplace版本效率更高,那让我们来看看效率高在哪里呢

int main()
{std::list<bit::string> lt;//传左值bit::string s1("ssssssss");lt.push_back(s1);lt.emplace_back(s1);cout << "********************************************" << endl;//传右值、lt.push_back(move(s1));lt.emplace_back(move(s1));cout << "********************************************" << endl;return 0;
}

在这里插入图片描述
我们发现传右值和左值它们的效率是一样的。

在这里插入图片描述
我们如果直接传参,就发现emplace版本只进行了一次构造就能完成,这是为什么呢?
在这里插入图片描述
我们的push_back在创建类对象时就确定了T为string类型,而emplace_back是直接推演的,推演为const char* 这个对象就可以直接构造string类型。

我们再试试插入的是pair的对象。

int main()
{std::list<pair<bit::string, int>> lt3;// 传左值效率用法都是一样的pair<bit::string, int> kv1("xxxxxx", 1);lt3.push_back(kv1);lt3.emplace_back(kv1);cout << "*****************************************" << endl;// 传右值效率用法都是一样的pair<bit::string, int> kv2("xxxxxx", 1);lt3.push_back(move(kv2));pair<bit::string, int> kv3("xxxxxx", 1);lt3.emplace_back(move(kv3));cout << "*****************************************" << endl;// emplace_back的效率略高一筹lt3.push_back({ "11111111111111", 1 });//lt3.emplace_back({ "11111111111111", 1 }); //不支持lt3.emplace_back("11111111111111", 1);cout << "*****************************************" << endl;return 0;
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

http://www.dtcms.com/a/393526.html

相关文章:

  • 常用设计模式中的工厂模式,责任链模式,策略模式和单例模式的简单说明
  • aave v3 合约解析1 存款
  • autosar中自旋锁和互斥锁的应用
  • 建筑可视化告别“假”渲染:用Photoshop+Twinmotion打造照片级场景
  • 一键生成linux服务器健康巡检html报告
  • 数据结构(C语言篇):(十八)交换排序
  • Ubuntu20.04下跑通ORB-SLAM2
  • C++二进制转十进制
  • WordPress用户系统 + JWT认证:打造统一的应用登录解决方案
  • PortSwigger靶场之将反射型 XSS 注入到带有尖括号和双引号的 JavaScript 字符串中,并使用 HTML 编码和单引号进行转义通关秘籍
  • win11电脑按键失灵,提供几个可能恢复的方法
  • Android 中获取稳定时间的方法
  • mac编译ffmpeg
  • Deepsoil V7.1.10+Shake2000,最新版程序、教学视频、PDF使用手册
  • Apollo相机数据RTMP推流与播放指南
  • 使用Python扩展Unity编辑器
  • 【Android】自定义控件
  • 探索 Event 框架 6:高级特性与性能优化
  • JavaSE基础——第九章 枚举类注解
  • 云计算在金融领域中的应用
  • 【入门算法】前缀和:先预存再求和,以空间换时间
  • mac编译vst3sdk
  • Java 网络原理(二)--- TCP的机制 + IP协议 +以太网协议 + DNS
  • Python文件名编码处理深度解析:绕过编码问题的专业指南
  • 如何利用简单的浏览器插件Web Scraper爬取知乎评论数据
  • 鹿鼎记豪侠传:Rust 重塑 iOS 江湖(下)
  • 03.博客版-镜像
  • 云原生docker离线二进制安装
  • RabbitMQ 的配置文件位置及常见配置项
  • Visual Prompt Builder-AI 提示词可视化工具