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

C++ 模板参数包展开方式

C++ 模板参数包展开方式

在 C++ 中,模板参数包(Template Parameter Pack)是 C++11 引入的一个强大特性,允许模板接受可变数量的参数。参数包展开(Parameter Pack Expansion)是将参数包解包为单独元素的过程。以下是主要的参数包展开方式:

1. 基本展开方式

template<typename... Args>
void func(Args... args) {// Args... 和 args... 都是参数包展开other_func(args...); // 展开为 other_func(arg1, arg2, ..., argN)
}

2. 递归展开

最常见的展开方式是通过递归模板实例化:

// 基本情况
void print() {std::cout << std::endl;
}// 递归情况
template<typename T, typename... Args>
void print(T first, Args... args) {std::cout << first << " ";print(args...); // 递归展开
}

3. 使用逗号运算符展开

template<typename... Args>
void print_all(Args... args) {(void)(std::cout << ... << args); // C++17 折叠表达式// 或使用逗号运算符展开int dummy[] = { (std::cout << args << " ", 0)... };(void)dummy; // 避免未使用变量警告
}

4. 初始化列表展开

template<typename... Args>
std::vector<int> make_vector(Args... args) {return std::vector<int>{args...}; // 展开为 {arg1, arg2, ..., argN}
}

5. 折叠表达式 (C++17)

C++17 引入了折叠表达式,简化了参数包展开:

template<typename... Args>
auto sum(Args... args) {return (args + ...); // 展开为 arg1 + arg2 + ... + argN
}template<typename... Args>
void print(Args... args) {(std::cout << ... << args); // 展开为 std::cout << arg1 << arg2 << ... << argN
}

6. 模板参数展开

template<typename... Args>
struct Tuple {std::tuple<Args...> data; // 展开为 std::tuple<Arg1, Arg2, ..., ArgN>
};

7. 完美转发展开

template<typename... Args>
void wrapper(Args&&... args) {target_func(std::forward<Args>(args)...); // 完美转发展开
}

8. 模式展开

可以在更复杂的模式中展开参数包:

template<typename... Args>
void foo(Args... args) {bar(&args...); // 展开为 bar(&arg1, &arg2, ..., &argN)baz(std::pair<Args, int>(args, 0)...); // 展开为 baz(pair<Arg1, int>(arg1, 0), ...)
}

注意事项

  1. 参数包展开必须有一个上下文(如函数调用、初始化列表等)
  2. 展开的语法是在参数包名后加 ...
  3. 参数包展开是编译时行为,不会产生运行时开销
  4. 在 C++17 之前,递归是处理参数包的主要方式

参数包展开是 C++ 模板元编程和泛型编程的强大工具,使得编写接受任意数量参数的通用代码成为可能。

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

相关文章:

  • 微服务架构设计规范
  • 详解GPU
  • 湖北理元理律师事务所观察:债务优化如何成为民生安全网
  • APM32微控制器键盘PCB设计实战教程
  • Docker 本地化部署FireCrawl
  • 《Pytorch深度学习实践》ch1-线性模型
  • Axure RP11安装、激活、汉化
  • ubuntu24.04与ubuntu22.04比,有什么新特性?
  • 增删改常用的元素
  • 欧盟MID认证,助力全球新能源高效计量与管理
  • leetcode hot100刷题日记——26.环形链表
  • 第七届下一代数据驱动网络国际学术会议(NGDN 2025)
  • JAVA重症监护系统源码 ICU重症监护系统源码 智慧医院重症监护系统源码
  • DMBOK对比知识点对比(2)
  • 【数据结构】栈和队列(下)
  • python打卡day39@浙大疏锦行
  • vite配置一个css插件
  • MySQL字段为什么要求定义为not null ?
  • 约瑟夫问题
  • insightface==0.7.3 编译失败
  • 从时钟精度看晶振频率稳定度的重要性
  • 12-后端Web实战(登录认证)
  • 实验设计与分析(第6版,Montgomery)第5章析因设计引导5.7节思考题5.4 R语言解题
  • Linux文件操作、文件夹操作
  • 【前端】使用grid布局封装断点式进度条
  • Flannel 支持的后端
  • 交集、差集、反选
  • 蓝牙和wifi相关的杂项内容总结
  • Executors面试题
  • apptrace 的优势以及对 App 的价值