如何构造同时携带普通参数的C++ variadic函数,能否实现填充vector的类似功能?
C++ 带普通参数的可变参数函数实现方案
1. 求和函数的修复方案
你原有代码编译失败的原因是i += args...不是合法的参数包展开语法,你之前实现的print函数使用了C++17引入的折叠表达式特性,求和逻辑也可以用相同的特性实现,两种常用写法如下:
template<class... Args> void add(int &i, Args... args) { // 写法1:先对所有参数求和,再赋值给i,等价于 i = i + arg1 + arg2 + arg3 + ... i += (... + args); } template<class... Args> void add2(int &i, Args... args) { // 写法2:逐个累加参数,等价于 ((i += arg1) += arg2) += arg3 ...,适合自定义类型重载+=的场景 (... , (i += args)); } void test(){ int i = 0; add(i, 1, 2, 3); // 最终i的值为6 }
2. 向vector填充元素的实现
标准库的std::vector是同构容器,同一个实例只能存储相同类型的元素,根据需求可以分为两种场景实现:
场景1:所有待插入元素可隐式转换为vector的元素类型
直接用折叠表达式调用push_back即可,支持完美转发避免多余拷贝:
#include <vector> #include <string> #include <utility> template<class T, class... Args> void fill_vector(std::vector<T>& vec, Args&&... args) { (vec.push_back(std::forward<Args>(args)), ...); } void test_vector() { std::vector<int> v1; fill_vector(v1, 1, 2, 3, 'a'); // 'a'会隐式转换为ASCII码97存入,最终v1为[1,2,3,97] std::vector<std::string> v2; fill_vector(v2, "hello", "world", std::string("test")); // 字面量会自动转为string存入 }
场景2:需要存储不同类型的元素
如果确实需要在同一个vector中存储多种类型的元素,可以使用C++17引入的std::variant作为vector的元素类型:
#include <vector> #include <variant> #include <string> #include <iostream> #include <utility> // 示例中variant支持存储int、double、std::string三种类型,可按需扩展支持的类型列表 template<class... Args> void fill_variant_vector(std::vector<std::variant<int, double, std::string>>& vec, Args&&... args) { (vec.emplace_back(std::forward<Args>(args)), ...); } void test_variant_vector() { std::vector<std::variant<int, double, std::string>> v; fill_variant_vector(v, 1, 3.14, "test"); // 访问variant元素可以用std::visit自动匹配类型 for (const auto& val : v) { std::visit([](auto&& arg) { std::cout << arg << " "; }, val); } // 输出结果:1 3.14 test }
内容的提问来源于stack exchange,提问作者Flow
相关产品推荐
相关产品推荐

