You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++23中对两个容器的enumerated zip进行遍历?

在C++23中实现类似Python enumerate(zip(A,B))的遍历

想要在C++23里实现和Python中enumerate(zip(A,B))一样的遍历效果——同时获取索引以及两个容器的对应元素。Python里的实现很直观:

A = [10, 20, 30]
B = [40, 50, 60]
for (i, (a, b)) in enumerate(zip(A, B)):
  print(i, a, b)

这段代码会依次输出索引i和A、B中对应的元素。

虽然C++23的<ranges>库提供了views::enumerate和views::zip这两个等效视图,但直接嵌套使用时会出现编译错误:

#include <vector>
#include <ranges>
#include <iostream>

using namespace std;

int main() {
  auto A = vector {10, 20, 30};
  auto B = vector {40, 50, 60};
  
  // 编译失败的写法
  for (auto [i, [a, b]]: views::enumerate(views::zip(A, B)))
    cout << i << " " << a << " " << b << "\n";
}

编译错误信息包括:

Type 'std::ranges::enumerate_view<...>::_Iterator::__reference_type' (aka 'tuple<long, std::pair<int &, int &>>') decomposes into 2 elements, but only 1 name was provided
Expected identifier

错误原因

问题出在结构化绑定的语法上。views::enumerate返回的每个元素是一个tuple,其中第一个元素是索引,第二个元素是views::zip生成的pair<int&, int&>。C++不支持直接用[i, [a, b]]这种嵌套方括号的结构化绑定写法,方括号在这里会被解析成其他语法,导致编译器无法正确识别绑定的变量名。

解决方案

方法1:拆分结构化绑定

先把enumerate返回的tuple拆成索引i和zip生成的pair,再对pair做二次结构化绑定:

#include <vector>
#include <ranges>
#include <iostream>

using namespace std;

int main() {
  auto A = vector {10, 20, 30};
  auto B = vector {40, 50, 60};
  
  for (auto [i, ab_pair]: views::enumerate(views::zip(A, B))) {
    auto [a, b] = ab_pair;
    cout << i << " " << a << " " << b << "\n";
  }
}

方法2:使用圆括号调整绑定结构

C++允许用圆括号来表示嵌套的结构化绑定,把zip返回的pair的绑定用圆括号包裹,替换原来的方括号:

#include <vector>
#include <ranges>
#include <iostream>

using namespace std;

int main() {
  auto A = vector {10, 20, 30};
  auto B = vector {40, 50, 60};
  
  // 正确的写法:用圆括号代替方括号
  for (auto [i, (a, b)]: views::enumerate(views::zip(A, B)))
    cout << i << " " << a << " " << b << "\n";
}

运行结果

两种写法都能正常编译运行,输出结果和Python代码一致:

0 10 40
1 20 50
2 30 60

内容的提问来源于stack exchange,提问作者Dan Oak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 06:05:17