在基于范围的循环中迭代数组的一部分

Iterating over a part of an array in a range-based loop

本文关键字:循环 数组 一部分 迭代 于范围 范围      更新时间:2023-10-16

是否有任何方法可以在c++ 11基于范围的循环中迭代数组的一部分?假设我有一个整型的someArray[10000000],但我只想迭代n的前一个元素。因此,我不能简单地使用

for(auto elem: someArray) {//doStuff}

有没有办法限制循环的范围,同时仍然使用基于范围的好东西?

简单地将范围调整为begin()end()做正确事情的不同类型。

struct Slice {
  int* arr;
  size_t n;
  int* begin() { return arr; }
  int* end() { return arr + n; }
};
for(auto elem : Slice{someArray, 100}) {/*doStuff*/}

如果不为它编写自己的包装器,c++ 11就没有办法做到这一点。另一种选择是使用具有view::slice的Range-V3 (查看):

#include <iostream>
#include <range/v3/view.hpp>
int main() {
  int arr[10] = {1,2,3,4,5,6,7,8,9,10} ;
  using namespace ranges;
  auto rng = arr |  view::slice(3, 6);
  for( auto &item : rng )
  {
      std::cout << item << ", " ;
  }
  std::cout << std::endl ;
}

另一方面,如果c++ 14可用,那么GSL array_view将是一个可行的选择:

gsl::array_view<int> av(arr+3,3) ;
for( auto &item : av )
{
    std::cout << item << ", " ;
}
std::cout << std::endl ;

GSL -lite提供了一个在c++ 11中工作的最小的GSL实现。

使用c++ 20 std::span即可。

for (auto elem : std::span(someArray).first(n))
  std::cout << elem;

No。

在c++ 17中有一些东西将使这成为可能,例如std::rangestd::array_view

但在此之前,只要使用好的旧迭代器或索引for,它将是最可读的:

for(auto i = 0u; i < n; ++i)
{
    // do the stuffs on someArray[i]
}

基于范围的for循环遍历整个范围。你所能做的就是存储一个额外的索引,在每次查看时检查。

size_t index = 0;
for(auto elem: someArray) 
{
   //doStuff
   if(index++ > n) break;
}

然而,我看不出这样做比普通的for循环有什么好处。

Ofc,您也可以在所需的子范围上使用std::for_each,但我仍然更喜欢传统的for循环。