C++模板参数包扩展与折叠表达式支持可变参数的编译时处理,用于函数转发、编译计算、代码生成和类型推导,相比std::initializer_list更灵活高效,适用于异构类型和零运行时开销场景。

C++模板参数包扩展与折叠表达式,本质上是为了更灵活、更简洁地处理数量不定的模板参数。它们是现代C++元编程的基石,允许我们编写泛型代码,而无需预先知道参数的数量和类型。
参数包扩展与折叠表达式是C++11和C++17引入的特性,允许函数和类模板接受可变数量的参数。
解决方案
C++模板参数包扩展与折叠表达式主要应用于以下几个方面:
立即学习“C++免费学习笔记(深入)”;
下面分别给出示例:
函数参数转发:
template<typename F, typename... Args>
auto call_with_args(F&& f, Args&&... args) {
return f(std::forward<Args>(args)...);
}
void print_args(int a, double b, std::string c) {
std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}
int main() {
call_with_args(print_args, 10, 3.14, "hello"); // 输出: a: 10, b: 3.14, c: hello
return 0;
}编译时计算 (折叠表达式):
template<typename... Args>
auto sum(Args... args) {
return (args + ...); // 右折叠,等价于 (arg1 + (arg2 + (arg3 + ...)))
}
int main() {
std::cout << sum(1, 2, 3, 4, 5) << std::endl; // 输出: 15
return 0;
}代码生成 (结合初始化列表):
#include <iostream>
#include <vector>
template<typename T, typename... Args>
std::vector<T> make_vector(Args&&... args) {
return {std::forward<Args>(args)...};
}
int main() {
std::vector<int> v = make_vector<int>(1, 2, 3, 4, 5);
for (int x : v) {
std::cout << x << " ";
}
std::cout << std::endl; // 输出: 1 2 3 4 5
return 0;
}类型推导 (元组):
虽然参数包本身不直接进行类型推导,但可以结合
std::tuple
#include <iostream>
#include <tuple>
template<typename... Args>
auto make_tuple(Args&&... args) {
return std::make_tuple(std::forward<Args>(args)...);
}
int main() {
auto my_tuple = make_tuple(10, 3.14, "world");
std::cout << std::get<0>(my_tuple) << std::endl; // 输出: 10
std::cout << std::get<1>(my_tuple) << std::endl; // 输出: 3.14
std::cout << std::get<2>(my_tuple) << std::endl; // 输出: world
return 0;
}参数包扩展的核心在于将一个参数包“展开”成一个逗号分隔的列表。这个列表可以出现在函数参数列表、初始化列表、基类列表等多种上下文中。展开的过程是由编译器完成的,它会根据参数包中的元素数量和类型,生成相应的代码。
理解的关键点在于
...
typename... Args
Args
Args&&... args
Args
f(args...)
f(std::forward<Args>(args)...)
Args
f
C++17引入了折叠表达式,它提供了一种更简洁的方式来处理参数包。折叠表达式有四种形式:
(pack op ...)
(e1 op (e2 op (e3 op ... en)))
(... op pack)
(((e1 op e2) op e3) op ... en)
(pack op ... op init)
(e1 op (e2 op (e3 op ... (en op init))))
(init op ... op pack)
(((((init op e1) op e2) op e3) op ... en)
其中,
pack
op
init
+
-
*
/
&&
||
,
例如,求参数包中所有元素的乘积:
template<typename... Args>
auto product(Args... args) {
return (args * ... * 1); // 带初始值的右折叠,初始值为1
}
int main() {
std::cout << product(1, 2, 3, 4, 5) << std::endl; // 输出: 120
return 0;
}std::initializer_list
虽然
std::initializer_list
std::initializer_list
std::initializer_list
std::initializer_list
因此,参数包扩展比
std::initializer_list
std::initializer_list
以上就是C++模板参数包扩展 折叠表达式应用的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号