如何在 C++23 中迭代 2 个容器的“枚举 zip”?

Dan*_*Oak 4 c++ std-ranges c++23

如何在 C++23 中迭代 2 个容器的“枚举 zip”?
在Python中,我会写这样的东西:

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

它依次输出和中的索引i和相应元素。AB

在 C++23 中enumeratezip存在等效项 ( <ranges>),但我不知道如何正确组合它们。

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

  // zip and enumerate? nope. does not compile:
  for (auto [i, [a, b]]: views::enumerate(views::zip(A, B)))
    cout << i << " " << a << " " << b << "\n";
Run Code Online (Sandbox Code Playgroud)

第一个方括号中的第一个错误[i, [a, b]]是:

类型 'std::ranges::enumerate_viewstd::ranges::zip_view<std::ranges::ref_view<std::vector<int>、std::ranges::ref_viewstd::vector<int>>>::_Iterator ::__reference_type' (又名 'tuple<long, std::pair<int &, int &>>')分解为 2 个元素,但仅提供了 1 个名称选择迭代器类型为 '_Iterator' 的 'begin' 函数

第二个方括号中的第二个错误:预期标识符

Nel*_*eal 5

我会使用std::views::iota来制作索引:

for (auto [i, a, b]: std::views::zip(std::views::iota(0), A, B)) {
    std::cout << i << " " << a << " " << b << "\n";
}
Run Code Online (Sandbox Code Playgroud)

演示

请注意,如果您愿意解压向量值(std::get例如使用或其他结构化绑定),则压缩和枚举方法确实有效:

for (auto [i, v]: std::views::enumerate(std::views::zip(A, B))) {
    std::cout << i << " " << std::get<0>(v) << " " << std::get<1>(v) << "\n";
    //
    // or
    //
    // std::cout << i << " " << v.first << " " << v.second << "\n";
    //
    // or
    //
    // auto [a, b] = v;
    // std::cout << i << " " << a << " " << b << "\n";
}
Run Code Online (Sandbox Code Playgroud)