C++能否在单个表达式中展开多个参数包以实现矩阵输出?
解决方案
你遇到的核心问题是单重参数包展开无法实现两个参数包的笛卡尔积遍历,必须使用嵌套展开逻辑,同时需要调整打印函数适配预期的空格分隔输出格式,完整实现方案如下:
适配调整
首先调整打印函数,避免每次输出换行:
void Print(int n){ std::cout << n << ' '; }
C++11 兼容实现
通过辅助模板函数实现两层参数包展开:
template < typename T1, typename T2 > struct Multi{}; template < int ... n > struct N{}; void Print(int n){ std::cout << n << ' '; } // 内层展开辅助:对固定的i,遍历所有n2的元素计算乘积并打印 template<int i, int... n2> void expand_inner() { using expander = int[]; (void)expander{ 0, ((void)Print(i * n2), 0)... }; } template < int ... n1, int ... n2 > struct Multi< N<n1...>, N<n2...>> { Multi() { using expander = int[]; // 外层遍历n1的所有元素,每个元素触发一次内层n2的完整展开 (void)expander{ 0, ((void)expand_inner<n1, n2...>(), 0)... }; } }; int main() { Multi< N<1,2,3,4>, N< 10,20> >{}; }
运行后输出为 10 20 20 40 30 60 40 80,符合预期输出顺序。
C++17 简化实现
使用折叠表达式可以省略辅助函数和expander定义,代码更简洁:
template < typename T1, typename T2 > struct Multi{}; template < int ... n > struct N{}; void Print(int n){ std::cout << n << ' '; } template < int ... n1, int ... n2 > struct Multi< N<n1...>, N<n2...>> { Multi() { // 双层折叠表达式:外层遍历n1,内层遍历n2 ([](int i) { (Print(i * n2), ...); }(n1), ...); } }; int main() { Multi< N<1,2,3,4>, N< 10,20> >{}; }
原写法问题说明
你原来的expander{ 0,((void)Print(n1...*n2),0)... };写法属于同位置参数包展开,只会匹配两个参数包相同位置的元素相乘,仅当两个参数包长度相等时可正常编译,无法实现笛卡尔积遍历需求。
内容的提问来源于stack exchange,提问作者Klaus
相关产品推荐
相关产品推荐

