带有常规C ++数组的Iterator或std :: iota? tl; dr:将数组包裹在一个“跨度”中

问题描述

有没有办法达到这个目的

std::list<int> l(10);
std::iota(l.begin(),l.end(),-4);

使用常规的int a[]吗?

或者,以下是唯一的解决方法

for (iterator itr = begin; itr != end; ++itr)
    /* ... visit *itr here ... */

解决方法

C ++ 11添加了std::beginstd::end。从那以后没有区别:

std::list<int> l(10);
std::iota(std::begin(l),std::end(l),-4);
int a[10];
std::iota(std::begin(a),std::end(a),-4);
,

tl; dr:将数组包裹在一个“跨度”中。

@ idclev463035818的answer是最简单的方法。但是,如果要将数组在多个上下文中视为标准库容器,请考虑将原始数组包装在一个范围中,如下所示:

auto a_ = std::span{a};

span是连续存储的轻量级引用类型。他们没有数据,因此您不复制阵列或任何东西。您可以在此处阅读有关跨度的更多信息:

What is a "span" and when should I use one?

无论如何,现在您可以编写:

std::iota(a_.begin(),a_.end(),-4);
for(x : a_) { do_stuff_with(x); }
auto c = std::ranges::count_if(a_,[](auto x) { return x > 3; });

,依此类推。也许更重要的是,如果将数组"decays" into a pointer传递给另一个函数,则不能再对其使用std::begin()std::end()了;可以跨度 传递,因此更健壮。

但是-std::span仅在以C ++ 20开头的标准中。例如,在此之前,您可以在gsl-lite library中使用span实现。