如何实现返回generator的模板驱动嵌套for循环生成多维数组下标?
解决方案:用cppcoro递归协程生成多维数组下标
核心思路
复用你现有的递归嵌套循环逻辑,将递归函数改造为返回cppcoro::generator的协程,利用co_yield from转发递归层级中生成的所有下标,最终在顶层协程中统一输出。
实现代码
#include <iostream> #include <array> #include <cppcoro/generator.hpp> using Size_t = size_t; using Int64_t = int; // 递归协程:生成指定维度的下标组合 template <size_t Index = 0, Size_t NLoops> cppcoro::generator<std::array<Int64_t, NLoops>> nested_for_loop( const std::array<Size_t, NLoops>& shape, std::array<Int64_t, NLoops>& outSubscripts) { if constexpr (Index == NLoops) { // 基例:当前已遍历所有维度,yield完整下标 co_yield outSubscripts; } else { // 递归分支:遍历当前维度的所有可能值 for (Size_t i = 0; i <= shape[Index]; ++i) { outSubscripts[Index] = i; // 转发下一层递归生成的所有下标组合 co_yield from nested_for_loop<Index + 1>(shape, outSubscripts); } } } // 对外接口:初始化下标数组并启动递归协程 template <Size_t NLoops> cppcoro::generator<std::array<Int64_t, NLoops>> generate_subscripts( const std::array<Size_t, NLoops>& shape) { std::array<Int64_t, NLoops> subscripts{}; co_yield from nested_for_loop(shape, subscripts); } int main() { std::array<Size_t, 3> shape = {2, 30, 6}; // 遍历生成的所有下标组合 for (const auto& subscript : generate_subscripts(shape)) { for (size_t i = 0; i < subscript.size(); ++i) { std::cout << subscript[i] << ' '; } std::cout << '\n'; } return 0; }
方案优势
- 零额外开销:完全复用你原有的递归循环逻辑,每个维度的下标直接循环赋值,无需计算线性索引转下标的乘法/加法,编译期通过模板递归展开,运行时无冗余分支。
- 扩展性强:支持任意编译期确定的维度数量,无需手动编写
if constexpr分支块。 - 接口简洁:通过
generate_subscripts包装函数隐藏内部递归细节,用户只需传入shape数组即可遍历所有下标。
关键细节说明
co_yield from是cppcoro协程的特性,用于将子协程中所有co_yield的值转发到父协程,这样递归层级中生成的每个下标都会被传递到顶层generator。- 模板参数
NLoops和Index都是编译期常量,因此递归分支会被编译器完全展开,运行时没有递归函数调用的额外开销(等价于手写嵌套for循环)。
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

