可变参数模板(参考《C++ Templates 英文版第二版》)

可变参数模板(参考《C++ Templates 英文版第二版》)

Chapter 4 可变参数模板

自从C++11,模板可以接受可变数量的参数

4.1 可变参数模板

可以定义模板,去接受无限数量的模板参数

这种行为的模板叫做可变参数模板

4.1.1 例子

#include <iostream>template<typename T>
void print(T arg)
{std::cout << arg << std::endl;
}template<typename T, typename... Types>
void print(T firstArg, Types... args)
{std::cout << firstArg << '\n';  // print first argumentprint(args...);                 // call print() for remaining arguments
}int main(int argc, char* argv[])
{print(1, 4, 7, "妙");
}

4.1.3 运算符sizeof

C++11 之后,sizeof操作符对于可变参数模板有新的用法sizeof...,他返回参数包里面包含多少个元素

template<typename T, typename... Types>
void print(T firstArg, Types... args)
{std::cout << sizeof... (Types) << std::endl;std::cout << sizeof... (args) << std::endl;
}

4.2 折叠表达式

C++11 提供了可变模板参数包, 使函数可以接受任意数量的参数. 但在 C++11中展开参数包稍显麻烦, 而 C++17 的折叠表达式使得展开参数包变得容易,其基本语法是使用 (...) 的语法形式进行展开.

支持的操作符

折叠表达式支持 32 个操作符: +, -, *, /, %, ^, &, |, =, <,>, <<, >>, +=, -=, *=, /=, %=, ^=, &=, |=, <<=,>>=,==, !=, <=, >=, &&, ||, ,, .*, ->*

  • 对于一元右折叠 (E op …) 具体展开为 E1 op (… op (EN-1 op EN)).
  • 对于一元左折叠 (… op E) 具体展开为 (( E1 op E2) op …) op En.
  • 对于二元右折叠 (E op … op I) 具体展开为 E1 op (… op (EN-1 op (EN op I))).
  • 对于二元左折叠 (I op … op E) 具体展开为 (((I op E1) op E2) op …) op E2.
// define binary tree structure and traverse helpers:
struct Node {int value;Node* left;Node* right;Node(int i=0) : value(i), left(nullptr), right(nullptr) {}//...
};
auto left = &Node::left;
auto right = &Node::right;// traverse tree, using fold expression:
template<typename T, typename... TP>
Node* traverse (T np, TP... paths) {return (np ->* ... ->* paths);      // np ->* paths1 ->* paths2 ...
}int main()
{// init binary tree structure:Node* root = new Node{0};root->left = new Node{1};root->left->right = new Node{2};//...// traverse binary tree:Node* node = traverse(root, left, right);//...
}

使用(np->* ... ->* paths)这个折叠表达式去遍历参数代表的路径

使用折叠表达式我们可以实现打印参数列表

template<typename ... Types>
void print(Types const&... args)
{(std::cout << ... << args) << '\n';
}int main()
{int a{ 12 };std::string b{ "博主是帅哥" };print(a, b);
}

但是我们这个函数有个小缺陷,就是无法打印空格,让我们来实现一下:

template<typename T>
class AddSpace
{private:T const& ref;                  // refer to argument passed in constructorpublic:AddSpace(T const& r): ref(r) {}friend std::ostream& operator<< (std::ostream& os, AddSpace<T> s) {return os << s.ref << ' ';   // output passed argument and a space}
};template<typename... Args>
void print (Args... args) {( std::cout << ... << AddSpace(args) ) << '\n';
}

运行:

int main()
{int a{ 12 };std::string b{ "博主是帅哥" };print(a, b);
}

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

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

相关文章

Curiously Recurring Template Pattern奇怪的模板递归 --- C++20

Curiously Recurring Template Pattern 奇怪的模板递归 — C20 我们都知道C有静态多态和动态多态,动态多态通过虚函数表实现,他的缺点就是对效率产生一点点影响 可以用CRTP解决这个问题 我们先举一个动态多态的例子: #include <iostream> using namespace std;class …

关于table的中元素对齐方式的注意点

情形一&#xff1a;<td></td>中嵌套了div或table元素。 1。td中的内部元素(如div)设置了height属性&#xff0c;td中设置了vertical-align的情况下&#xff0c;在IE中&#xff0c;td的vertical-align不起作用&#xff0c;但在firefox中是起作用的。 2。如果td中未…

不要带我去看鱼了

我在企业里面上班。每天中午都得回家吃午饭。儿子才3岁。每每见我总是要我抱&#xff0c;我经常出差什么的&#xff0c;儿子都怕我走了。每次我要离开的时候&#xff0c;只好让老婆抱着儿子遮住&#xff0c;让我悄悄地离开。儿子便猛哭。老婆只好带着儿子到家门口的池塘旁边去看…

char 与 String 相等比较

这是一个相当2 相当基础 相当没有意义的帖子&#xff1b;但今天因为这个问题引发了一个bug。小细节也很重要&#xff01;&#xff01;&#xff01; char a1;// char b2dsf; //char 表示单个字符 char c1; //不需要单引号也能表示// System.out.println(a.equals(&q…

我眼中的金蝶ERP

在我的博克回复里&#xff0c;有个小雨的博友问我是否了解金蝶ERP&#xff0c;我答应给她说说金蝶ERP&#xff0c;所以就有了这份文章。在我们国内&#xff0c;最出名的或者说市场占有率前两位的就是用友和金蝶了。至于到底谁排名先排名后一点&#xff0c;这不是我想说的范围。…

什么是JDO

From: http://blog.csdn.net/wp_84/archive/2007/09/02/1769481.aspx Java数据对象(Java Data Objects,JDO)是一个应用程序接口(API),它是Java程序员能够间接地访问数据库,也就是说,不需使用直接的结构化查询语言(SQL)语句.JDO是作为Java数据库连接(JDBC)的一个补充来介绍的,而…

PROJECT #0 - C++ PRIMER [CMU 15-445645]笔记

PROJECT #0 - C PRIMER [CMU 15-445/645]笔记 这是数据库领域的一门课程, 由卡内基梅隆大学副教授Andy Pavlo授课, 目前在网上有授课视频资料、实验以及配套的在线测评环境 (限时开放至2021年12月31日) 环境: wsl2 Clion Project #0 - C Primer 还是很简单的,主要目的是让…

简单JS实现对表的行的增删

这段代码非常的简单&#xff0c;仅仅作为自己的一个小小的记录&#xff01; ok&#xff0c;先上一个简单的图例&#xff0c;效果如下&#xff08;注意&#xff1a;这只是一个简单的例子&#xff0c;不过可以根据这个简单的例子&#xff0c;变化出更为复杂的效果&#xff09;&am…

用 JavaScript 操作字符串

虽然 JavaScript 有很多用处&#xff0c;但是处理字符串是其中最流行的一个。下面让我们深入地分析一下使用 JavaScript 操作字符串。在 JavaScript 中&#xff0c; String 是对象。 String 对象并不是以字符数组的方式存储的&#xff0c;所以我们必须使用内建函数来操纵它们的…

The Ranges Library --- C++20

The Ranges Library — C20 ranges可以让我们更加舒服的写代码了, 不用再敲那么多的代码 之前我们需要这样标准库的算法对容器的操作 #include <iostream> #include <ranges> #include <vector> #include <algorithm>int main() {std::vector vec{ …

什么是反射(.NET)[转]

From: http://www.cnblogs.com/zxsoft/archive/2007/09/17/895236.html 反射&#xff08;Reflection&#xff09;是.NET中的重要机制&#xff0c;通过放射&#xff0c;可以在运行时获得.NET中每一个类型&#xff08;包括类、结构、委托、接口和枚举等&#xff09;的成员&#x…

Yii权限管理工具Srbac使用小结

一、关于Srbac Srbac是基于Yii 框架的 RBAC&#xff08;基于角色的访问控制&#xff09; 插件模块&#xff0c;用于帮助Yii开发人员更方便地进行权限控制&#xff0c;在实际应用过程中也比较方便。 二、安装配置Srbac 在Yii的官方网站的Extensions中已经收录了Srbac插件&#x…

概念concept和requires ---C++ 20

概念concept和requires —C 20 concept concept简化了模板编程的难度 我们可以使用**concept定义模板形参的约束条件T** 模板实力替换T后必须满足std::is_integral_v<C>;为true 例子: requires关键字可以直接约束模板形参T 如下: template <class C> concept …

辞职中

不知道为什么就不想再做下去了&#xff0c;说不上来工作有什么好&#xff0c;当然也说不上来什么不好。SP这个行业&#xff0c;可能不太适合我。准备走了&#xff0c;考研还是继续找工作&#xff1f;我不知道该怎么走&#xff01;看着前面都是路却找不到一条适合自己的。转载于…

向DataGridView中添加新的一行数据,可以添加到最后一行或作为第一行

我的开发环境&#xff1a;Microsoft Visual Studio .net 2005 这个程序是Windows Forms Application 新建一个Windows Forms Application项目&#xff0c;打开Form1&#xff0c;在窗体上放一个DataGridView控件和Button,在DataGridView的Columns中添加两列&#xff0c;Name分别…