迭代容器的前 n 个元素 - std::span vs views::take vs ranges::subrange

Iterating over first n elements of a container - std::span vs views::take vs ranges::subrange

因此,在 c++ 20 中,我们获得了许多新功能,包括范围、跨度等。现在,如果我需要迭代一个容器,但只需要第一个 n 元素,什么是最合适的方法,幕后是否有任何实际差异?或者返回到带有索引的常规 for 循环可能是更好的主意,因为这些示例的性能可能较低?

for (const auto &e: elements | std::ranges::views::take(n)) {
// do stuff
}

for (const auto &e: std::span(elements.begin(), n)) {
// do stuff
}

for (const auto &e: std::ranges::subrange(elements.begin(), elements.begin() + n)) {
// do stuff
}
  • views::take是最通用的,它几乎适用于任何范围,例如input_rangeoutput_range以及更细化的范围。

  • std::span 适用于contiguous_range.

  • 虽然ranges::subrange也是泛型,但是由于需要通过elements.begin() + n获取迭代器的bound,这就要求elements必须是random_access_range.

另外值得注意的是,在P1739之后,views::take会根据范围的类型得到一个“合适”的范围类型,即当范围为span ,就会returnspan,当string_view,就会returnstring_view,当subrange,就会return subrange,当为iota_view时,会return iota_view.