C++ Variadic Templates(可变参数模板)

本文参考侯捷老师的视频:https://www.youtube.com/watch?v=TJIb9TGfDIw&list=PL-X74YXt4LVYo_bk-jHMV5T3LHRYRbZoH
以及C++ primer第五版 相关内容。

可变参数模板函数

//递归的终止条件
void print() {}
//Variadic Templates
//一般用于递归处理
template <typename T, typename... Types>
void print(const T& firstArg, const Types&... args) {cout << firstArg << endl;print(args...);
}

上面这个模板函数可以接收任意个数任意类型的参数并进行打印输出。其中typename... Types是可变模板参数,表示可以接收任意类型,Types... args表示可变函数参数,表示可以接收任意个数、任意类型的参数,要注意...在不同的位置,这些都是固定的。可以看到我们输出第一个参数以后,调用了print(args...),如果args中的参数个数大于0,则会继续调用模板函数,将第一个参数赋给firstArg,其余参数赋给args;如果参数个数等于0,则调用非模板函数void print()结束递归。

可以看出,可变参数模板函数是通过递归来进行参数解包的。

特殊的,如果我们将上面的函数写成下面的版本:

//递归的终止条件
template<typename T>
void print(const T& t) {cout << t << endl;
}
//Variadic Templates
//一般用于递归处理
template<typename T, typename... Types>
void print(const T& t, const Types&... args) {print(t);print(args...);
}

同样完成将所有参数进行打印的工作。但是可能会有疑惑,对于print(t),似乎既可以调用void print(const T& t),又可以调用void print(const T& t, const Types... args),那么编译器会调用哪一个呢?这个是确定的,编译器会调用void print(const T& t)。原因在于非可变参数版本比可变参数版本更加特例化。(详细模板重载规则见C++ primer 16.3 重载与模板)
在可变参数模板函数中,我们可以通过sizeof...(args)获得可变参数的个数,返回一个常量表达式。

如果运行下面的代码,仍然会和上面的有同样的效果,void print(const Types... args)不会运行:

//递归的终止条件
template<typename T>
void print(const T& t) {cout << t << endl;
}
//Variadic Templates
//一般用于递归处理
template<typename T, typename... Types>
void print(const T& firstArg, const Types&... args) {print(firstArg);print(args...);
}template<typename... Types>
void print(const Types&... args) {cout << sizeof...(args) << endl;
}

可变参数模板类

最经典的就是tuple,通过递归地继承自己,实现了可以包含任意个数、任意类型的数据结构。

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

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

相关文章

Ubuntu修复Fix Busybox Initramfs错误

今天早上我打开电脑&#xff0c;进入Ubuntu系统&#xff0c;结果黑屏了&#xff0c;屏幕显示&#xff1a; BusyBox v1.30.1 (Ubuntu 1:1.30.1-4ubuntu6.1) built-in shell (ash) Enter help for a list of built-in commands.(initramfs)然而我并不知道这个是什么意思&#x…

Leetcode第284场周赛

绪论 最近发现Leetcode每周的周赛难度挺适合我的&#xff0c;而且时间也比较友好&#xff08;不像Codeforces每次都是半夜&#xff09;。所以连续参加了三周的周赛。这次才想起来应该记录一下自己的参赛历程。一方面是总结经验&#xff0c;另一方面有了记录就更有动力去提升&a…

Leetcode第286场周赛

绪论 上周因为有事没有参加周赛&#xff0c;这周没有错过。这次周赛拿到了人生第一个AK&#xff0c;参加大大小小的比赛这么多次&#xff0c;从来没有AK过&#xff0c;泪目了。 感觉这次比赛的思维难度对我来讲稍高一些&#xff0c;前三道题就花了一个小时&#xff0c;而以往…

第287场周赛

绪论 虽然是上周日参加的比赛&#xff0c;但是这周没有怎么学习&#xff0c;每天就是玩耍。也导致对周赛的总结迟迟没有进行。想着再拖下去下次周赛都要开始了&#xff0c;在这里补一下。 这场比赛总体比上场简单一些&#xff0c;但是最后一道题因为忘记初始化类内变量导致调试…

第288场周赛

绪论 虽然没有AK&#xff0c;但是不知道为什么排名比以前AK了都靠前。可能是因为最后一道题有些难度&#xff0c;缩小了我和大佬之间的差距。最后一个小时写最后一道题&#xff0c;累死累活想了一个贪心遍历的算法&#xff0c;当时是一直RE&#xff0c;后来下来调了调又WA了。 …

Clion远程部署和运行

绪论 作为Clion的忠实粉丝&#xff0c;现在的我的几乎所有的coding都是通过Clion完成。因为需要在服务器上进行开发&#xff0c;又离不开Clion&#xff0c;就了解了如何通过Clion远程部署和开发。 主要是借鉴了博客&#xff1a;使用Clion优雅的完全远程自动同步和远程调试c。如…

C++ 单例模式 call_once : terminate called after throwing an instance of ‘std::system_error‘

在学习了C中可以使用call_once进行初始化资源后&#xff0c;我就想着写一个单例模板供以后使用。 template<typename T> class SingleTon {using Ptr std::shared_ptr<T>;static Ptr p;static std::once_flag flag;template<typename ...Args>static void …

C++读写锁造成死锁

C14支持std::shared_timed_mutex C17支持std::shared_mutex 前者相比后者支持的操作更多&#xff0c;但是后者相对性能更好。 使用std::lock_guard<std::shared_mutex>和std::unique_lock<std::shared_mutex>互斥访问使用std::shared_lock<std::shared_mutex…

每日一题:449. 序列化和反序列化二叉搜索树

题目分析 题目链接&#xff1a;449. 序列化和反序列化二叉搜索树 觉得序列化很简单&#xff0c;前序遍历、后序遍历、中序遍历、层序遍历等等。其中得到前序遍历和后序遍历是可以通过递归解法反序列化的&#xff0c;觉得这样子做有点复杂。就想着可不可以一次遍历。一次遍历的…

C++高效集合数据结构设计

绪论 在复杂算法实现过程中我们经常会需要一个高效的集合数据结构&#xff0c;支持常数级别的增、删、查&#xff0c;以及随机返回、遍历&#xff0c;最好还能够支持交集、并集、子集操作 哈希集合实现 大家可能很快想到unordered_set&#xff0c;unordered_set由于底层是哈…

C++ 工具函数库

在写一些大型项目的过程中经常需要一些工具函数&#xff0c;例如获取随机数、计时器、打印函数、重要常量&#xff08;如最大值&#xff09;、信号与槽等&#xff0c;由于每一个工程都自己手动实现一个实在是太傻&#xff0c;我将其总结放入一个文件中。 utils.h // Copyright…

muduo网络库使用入门

muduo网络库介绍 muduo网络库是陈硕大神开发的基于主从Reactor模式的&#xff0c;事件驱动的高性能网络库。 网络编程中有很多是事务性的工作&#xff0c;使用muduo网络库&#xff0c;用户只需要填上关键的业务逻辑代码&#xff0c;并将回调注册到框架中&#xff0c;就可以实…

C++ map/unordered_map元素类型std::pair<const key_type, mapped_type>陷阱

在开发的过程中需要遍历一个unordered_map然后把他的迭代器传给另一个对象&#xff1a; class A; class B { public:void deal(const std::pair<int, A>& item); }; std::unordered_map<int, A> mp; B b; for (auto &pr : mp) {b.deal(pr); }在我的项目中…

Ubuntu install ‘Bash to dock‘

绪论 在Ubuntu环境搭建这篇博客中记录了使用Dash To Dock来配置Ubuntu的菜单项&#xff0c;使得实现macOS一样的效果。为了配置新电脑的环境&#xff0c;我还是想安装这个软件。但是如今在Ubuntu Software中已经找不到这个软件了&#xff0c;我在网上借鉴了一些博客的经验才得…

Leetcode第309场周赛

Date: September 4, 2022 Difficulty: medium Rate by others: ⭐⭐⭐⭐ Time consuming: 1h30min 题目链接 竞赛 - 力扣 (LeetCode) 题目解析 2399. 检查相同字母间的距离 class Solution {public:bool checkDistances(string s, vector<int>& distance) {vec…

C++ 模板函数、模板类:如果没有被使用就不会被实例化

C中如果一个模板函数没有使用过&#xff0c;那么其局部静态变量都不会被实例化&#xff1a; class A { public:A() {edward::print("A ctor");} };template<typename T> void test() {static A a; }int main() {test<int>(); //如果注释掉则不会有输出r…

C++ 条件变量的使用

绪论 并发编程纷繁复杂&#xff0c;其中用于线程同步的主要工具——条件变量&#xff0c;虽然精悍&#xff0c;但是要想正确灵活的运用却并不容易。 对于条件变量的理解有三个难点&#xff1a; 为什么wait函数需要将解锁和阻塞、唤醒和上锁这两对操作编程原子的&#xff1f;为…

C++Primer学习笔记:第1章 开始

本博客为阅读《C Primer》&#xff08;第5版&#xff09;的读书笔记 ps:刚开始的时候我将所有的笔记都放在一篇博客中&#xff0c;等看到第六章的时候发现实在是太多了&#xff0c;导致我自己都不想看&#xff0c;为了日后回顾&#xff08;不那么有心理压力&#xff09;&#…

【ubuntu】ubuntu14.04上安装搜狗输入法

** 在ubuntu14.04.4 desktop 64amd版本上安装sogou输入法 ** 0.换安装源为中国源&#xff08;可选&#xff0c;下载会快些&#xff09; 1.搭fcitx环境 2.安装sogou for linux 详细步骤&#xff1a; 因为sogou中文输入法基于fcitx(Free Chinese Input Toy for X),需要先搭环境…

【ubuntu】ubuntu下用make编译程序报错找不到openssl/conf.h

ubuntu下用make编译程序报错找不到openssl/conf.h 安装libssl-dev:i386&#xff0c;sudo apt-get install libssl-dev:i386 看好版本&#xff0c;如果不加i386默认下载的是32位&#xff0c;用ln命令连接过去也还是用不了的!libssl.dev安装好后&#xff0c;用find / -name libs…