在C++11的范围-based循环中,有没有一种方法只遍历数组的一部分?比如说我有一个int 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*/}
size_t
来表示大小? - Neil Kirkfor
一起使用的数组几乎肯定是全局或自动的,因此不太可能太大以至于无法使用int
索引。能够创建10e7个元素的数组的系统可能至少具有32位的int
。如果没有,请使用更大的类型。 - Jonathan Wakely没有C++11的方法可以在不编写自己的包装器的情况下完成此操作。另一个选择是使用Range-V3,它具有view::slice
(请参见实时演示):
#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 ;
}
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;
目前标准中不支持这个功能。
在C++17中有一些正在开发中的功能可以实现这个,例如std::range
和std::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循环更有优势。
当然,你也可以在所需的子范围上使用std::for_each
,但我仍然更喜欢传统的for循环。
for
循环有什么问题吗? - Walter