IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 可变参数模板(参考《C++ Templates 英文版第二版》) -> 正文阅读

[数据结构与算法]可变参数模板(参考《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 argument
	print(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 constructor
  public:
    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);
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-04 13:05:02  更:2021-10-04 13:06:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 12:54:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码