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

《C++ Primer 第五版》省略符号(...)

在 C 语言里:可变参数函数(printf 风格)

在 C 语言里,省略号 ... 出现在函数参数列表里,表示参数个数不固定

最典型的例子就是 printf

#include <stdio.h>
#include <stdarg.h>void myPrint(const char *fmt, ...) {   // ... 表示不定数量参数va_list args;va_start(args, fmt);while (*fmt) {if (*fmt == 'd') {int i = va_arg(args, int);printf("%d\n", i);}fmt++;}va_end(args);
}int main() {myPrint("ddd", 10, 20, 30);  // 传了三个 intreturn 0;
}

🔑 要点:

  • ... 代表“剩下的参数”

  • 需要 <stdarg.h> 里的宏 (va_list, va_start, va_arg, va_end) 才能取出

  • 缺点:类型不安全,编译器不会检查传入的类型(传错类型可能崩溃)


2️⃣ 在 C++ 语言里:模板参数包(可变参数模板)

C++11 引入了 可变参数模板,也是用 ...
和 C 不同,它是编译期展开,类型安全。

例子:

#include <iostream>
using namespace std;void print() { } // 递归出口template<typename T, typename... Args>
void print(T first, Args... rest) {cout << first << " ";print(rest...);   // 展开递归
}int main() {print(1, 2.5, "hello", 'A');  // 任意类型,安全return 0;
}

输出:

1 2.5 hello A

🔑 要点:

  • typename... Args 定义一个参数包

  • rest... 展开这个参数包

  • 类型安全,编译器会检查每个实参的类型


3️⃣ 在函数调用里:参数包展开

C++ 里 ... 还能用来 展开一组参数

例子:

template<typename... Args>
void call(Args... args) {foo(args...);   // 把参数原样传给 foo
}


4️⃣ 其他用法:折叠表达式(C++17)

C++17 引入了 折叠表达式,简化了可变参数的处理:

template<typename... Args>
int sum(Args... args) {return (args + ...);  // 从左到右展开:((a+b)+c)+d ...
}int main() {cout << sum(1,2,3,4,5) << endl; // 15
}

相比递归调用更优雅。


5️⃣ 总结口诀

  • C 的 ... = “袋子”,丢多少个参数进去都行,但取出来要小心(用 va_arg),类型不安全。

  • C++ 的 ... = “魔法展开符”,可以把一包模板参数展开成一串,既灵活又安全。

  • C++17 之后,还能写折叠表达式,更简洁。


👉 形象比喻:

  • C 的 ... 像是快递袋子,里面放什么快递员不管,你自己拆开得对照单子,不然拆错了就坏了。

  • C++ 的 ... 像是拼装积木,编译器帮你一块块展开拼起来,不会出错。

http://www.xdnf.cn/news/18714.html

相关文章:

  • 【小增长电商技术分享】电商支付宝批量转账工具技术测评:架构特性、合规风险与选型方法论,支付宝官方|小增长|云方付|易推客省心返
  • vi/vim 查找字符串
  • Ajax笔记(上)
  • Spark面试题
  • Redis面试精讲 Day 30:Redis面试真题解析与答题技巧
  • 南京魔数团:AR技术引领远程协作新纪元
  • Java网络编程:从入门到精通
  • STM32之DMA详解
  • 算法题记录01:
  • 8月25日
  • 专题:2025人工智能2.0智能体驱动ERP、生成式AI经济现状落地报告|附400+份报告PDF、原数据表汇总下载
  • [论文阅读]RQ-RAG: Learning to Refine Queries for Retrieval Augmented Generation
  • k8s的etcd备份脚本
  • AR技术赋能农业机械智能运维
  • 电机控制::基于编码器的速度计算与滤波::RLS
  • 【C++】第二十六节—C++11(中) | 右值引用和移动语义(续集)+lambda
  • Linux_用 `ps` 按进程名过滤线程,以及用 `pkill` 按进程名安全杀进程
  • 机器学习-大语言模型Finetuning vs. Prompting
  • 大型语言模型基准测试综述《A Survey on Large Language Model Benchmarks.pdf》核心内容总结
  • 京东前端社招面经
  • 多维度指标交叉计算查询方案
  • 【芯片后端设计的灵魂:Placement的作用与重要性】
  • 6、RocketMQ消息积压问题如何解决
  • Python爬虫实战:Selenium模拟操作爬取马蜂窝旅游攻略
  • 数据挖掘 6.1 其他降维方法(不是很重要)
  • redis----list详解
  • 深度学习入门第一课——神经网络实现手写数字识别
  • 读《精益数据分析》:A/B测试与多变量测试
  • 【栈 - LeetCode】739.每日温度
  • [Java恶补day51] 46. 全排列