C++中如何将可变参数模板的参数正确存入数组?
问题根因
你遇到的问题来自对折叠表达式和逗号运算符的逻辑误解:
- 你写的
(values, ...)是逗号运算符的一元右折叠,展开后等价于((((1, 2), 3), 4), 5), 6。C++逗号运算符会依次求值两侧表达式,但整个表达式的返回值只有最后一个操作数,也就是6。 - 这就导致数组初始化列表实际只收到1个有效值6,剩余未被显式初始化的数组元素会被零初始化,最终输出
[6,0,0,0,0,0]。 - 额外注意:原生数组如果用运行期长度属于非标准C++扩展,虽然你这里用
sizeof...得到的是编译期常量,但用std::array是更稳妥的标准写法。
直接在初始化列表填充的实现方案
不需要额外循环或者std::vector插入操作,直接在初始化列表中展开参数包即可,语法非常简洁:
#include <iostream> #include <array> #include <utility> // for std::forward template <typename... var_args_t> void putArgumentsToArray(var_args_t&&... values) { constexpr std::size_t num_args = sizeof...(var_args_t); // 直接展开参数包,按传入顺序填充数组,static_cast统一转换为目标元素类型int std::array<int, num_args> values_array{ static_cast<int>(std::forward<var_args_t>(values))... }; for (std::size_t i = 0; i < num_args; ++i) { std::cout << values_array[i] << "\n"; } } int main() { putArgumentsToArray(1, 2, 3, 4, 5, 6); // 输出顺序为1到6,完全符合预期 }
写法说明
- 核心逻辑是
static_cast<int>(values)...:参数包展开后会自动用逗号分隔所有参数,正好匹配聚合初始化的列表格式,每个参数会按传入顺序作为数组对应位置的初始化值。 - 如果你一定要使用原生数组,只要将数组定义替换为
int values_array[num_args] = { static_cast<int>(values)... };即可,效果完全一致。 - 加入
std::forward是为了完美转发传入参数的值类别,避免不必要的拷贝,如果不需要处理右值引用场景可以省略,直接写static_cast<int>(values)...也能正常运行。 - 如果需要适配不同的参数类型,可以用
std::common_type_t<var_args_t...>作为数组元素类型,自动推导所有参数的公共类型。
内容的提问来源于stack exchange,提问作者Zebrafish
相关产品推荐
相关产品推荐

