如何在C++中用可变模板实现不同类型向量的无硬编码循环组合
问题解答
1. 可变模板实现不同类型向量的全组合
完全可以通过C++可变模板实现不同类型容器的全组合生成。核心思路是利用递归展开可变参数包:每次处理一个类型的容器,将当前容器的每个元素与之前已生成的所有组合结果进行组合,直到遍历完所有参数包中的容器类型。
2. 支持自定义std::function处理逻辑
当然支持传入std::function自定义组合逻辑,无需硬编码字符串拼接。只需要将组合逻辑作为参数传入递归函数,让每一步的元素组合都调用用户提供的处理函数即可,极大提升灵活性。
示例代码
#include <iostream> #include <vector> #include <string> #include <functional> #include <sstream> // 递归终止条件:所有容器处理完毕,触发结果处理 void generate_combinations(const std::function<void(const std::string&)>& handler) { handler(""); } // 递归展开可变参数包:处理当前容器,与之前的组合结果合并 template<typename T, typename... Rest> void generate_combinations(const std::vector<T>& current_vec, const std::function<void(const std::string&)>& handler, const std::function<std::string(const std::string&, const T&)>& combiner, Rest... rest) { // 先递归处理剩余容器,拿到前置组合结果 generate_combinations([&](const std::string& prev) { // 遍历当前容器元素,用自定义逻辑合并前置结果与当前元素 for (const auto& elem : current_vec) { std::string combined = combiner(prev, elem); handler(combined); } }, combiner, rest...); } // 初始调用重载:适配无前置结果的入口 template<typename... Args> void generate_combinations(const std::function<void(const std::string&)>& handler, const std::function<std::string(const std::string&, const auto&)>& combiner, Args... args) { generate_combinations(args..., handler, combiner); } int main() { // 不同类型的输入向量 std::vector<std::string> str_vec = {"T", "U"}; std::vector<int> int_vec = {1, 2}; std::vector<float> float_vec = {1.1f, 2.2f}; // 自定义组合逻辑:实现"前置结果-当前元素"的拼接格式 auto combiner = [](const std::string& prev, const auto& elem) -> std::string { std::ostringstream oss; if (!prev.empty()) { oss << prev << "-"; } oss << elem; return oss.str(); }; // 自定义结果处理逻辑:打印每个生成的组合 auto handler = [](const std::string& result) { std::cout << result << std::endl; }; // 触发全组合生成 generate_combinations(handler, combiner, str_vec, int_vec, float_vec); return 0; }
代码说明
- 递归终止函数负责启动最终的结果处理流程;
- 可变模板递归函数依次处理每个容器,通过用户传入的
combiner函数完成元素与前置组合的合并; combiner可自由定义格式逻辑(示例用-分隔,也可替换为其他符号或复杂处理);handler负责处理最终生成的每个组合(比如打印、存储到容器、业务逻辑处理等)。
运行代码会输出所有可能的组合:
T-1-1.1 T-1-2.2 T-2-1.1 T-2-2.2 U-1-1.1 U-1-2.2 U-2-1.1 U-2-2.2
内容的提问来源于stack exchange,提问作者Duke
相关产品推荐
相关产品推荐

