栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

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

4.1 可变参数模板

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

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

4.1.1 例子
#include 

template
void print(T arg)
{
	std::cout << arg << std::endl;
}

template
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
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
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
void print(Types const&... args)
{
	(std::cout << ... << args) << 'n';
}

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

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

template
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 s) {
      return os << s.ref << ' ';   // output passed argument and a space
    }
};

template
void print (Args... args) {
  ( std::cout << ... << AddSpace(args) ) << 'n';
}

运行:

int main()
{
	int a{ 12 };
	std::string b{ "博主是帅哥" };
	print(a, b);
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/289594.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号