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

可变参数模版中的折叠表达式

C++17 后,有一个特性可以对参数包的所有参数使用二元运算符计算结果(初始值可选)。

例如,下面的函数会返回所有入参的和:

template<typename... T>
auto foldSum (T... s)
{return (... + s); // ((s1 + s2) + s3) ...
}

若参数包为空,表达式通常是错误格式的(除了操作符&& 的值为true,操作符|| 的值为false,逗号操作符空参数包的值为void())。

下表列出了可能的折叠表达式。

折叠表达式 展开
( ... op pack ) ((( pack1 op pack2 ) op pack3 ) ... op packN )
( pack op ... ) ( pack1 op ( ... ( packN-1 op packN )))
( init op ... op pack ) ((( init op pack1 ) op pack2 ) ... op packN )
( pack op ... op init ) ( pack1 op ( ... ( packN op init )))

几乎所有的二元运算符都可以使用折叠表达式。例如,可以使用折叠表达式来遍历一个二叉树的路径,使用操作符->*:

foldtraverse.cpp

// 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)

使用折叠表达式遍历从 np 开始的可变元素路径。

这种使用初始化器的折叠表达式,可以简化可变参数模板来打印上面的所有参数:

template<typename... Types>
void print (Types const&... args)
{(std::cout << ... << args) << '\n';
}

但无法为参数包中的每个元素输出添加打印空格。要添加空格,需要一个额外的类模板,确保参数的输出都会添加一个空格:

addspace.hpp

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';}

表达式AddSpace(args) 使用类模板参数推断产生AddSpace(args),这为每个参数创建一个AddSpace 对象,该对象引用传递的参数,并在输出表达式时使用该参数添加一个空格。

http://www.jsqmd.com/news/65619/

相关文章:

  • scikit-learn 能否做深度学习?——兼谈不同神经元数量的模型对比实验实现
  • 吟诗一首
  • 二分查找
  • 深入解析USB侦探:数字取证数据流分析技术
  • Oracle数据库性能诊断与SQL优化实战指南
  • 56
  • re:MARS 2022:聚焦机器学习与机器人技术的年度盛会
  • 深入解析:Spring Boot 3.2 高性能架构实战:虚拟线程、原生镜像与响应式编程全解析
  • CMake-模块化
  • 测试用例的编写和注意事项
  • 割点和桥
  • AI元人文构想全维解构:从意义行为原生到文明价值操作系统
  • YII框架的三条经典利用链的探究
  • HELLDIVERS 2 地狱潜兵 2 缩小体积至22.54G 教程
  • 深度解析人工神经元输入机制
  • Milvus GUI ATTU Docker 容器化部署指南
  • 如何使用QFontDatabase在Qt应用程序中嵌入字体
  • 人工神经元输入机制深度解析:从理论基础到工程实践的全面指南
  • 贪心 [CSP-S 2025] 社团招新
  • 12月7日总结 - 作业----
  • P7115 [NOIP2020] 移球游戏 题解
  • pdf图片处理
  • 2025年12月本田雅阁更换轮胎推荐:最新性能测评与选购攻略
  • 获取运行中的exe的窗口标题名
  • 2025年大众帕萨特更换轮胎推荐:玲珑、米其林、马牌哪个是全面优选?
  • 12.7
  • 安卓页面的布局和生命周期(新手村第三篇) - 详解
  • 《场景化落地:用 Linux 共享内存解决进程间高效数据传输障碍(终篇)》
  • 本地AI模型API网址添加到Open WebUI的方法
  • 图像基础核心知识体系