迭代顺序集合的习惯用法

Idioms for iterating a sequential collection

本文关键字:习惯 惯用法 集合 顺序 迭代      更新时间:2023-10-16

在现代c++中,当您只需要每个元素的值时,迭代顺序集合(如string或vector)的习惯用法是简短而优雅的:

for (auto x: xs)

当您还需要索引时,它就不那么优雅了:

for (size_t i = 0; i != xs.size() ++i)

…除非最近有什么进展我还没跟上c++ 11是否有一种更好的方法来实现后者,或者上述方法仍然是最好的吗?

Range-Based for loops将在现代代码Range-Based for Loops中非常流行对支持范围概念的任何类型都有效。给定T型对象obj, begin(obj)end(obj)是有效的。包括:

  • 所有c++ 11库容器。
  • 数组和值数组。
  • 初始化器列表。
  • 正则表达式匹配。
  • 任何UDT(用户定义类型)T,其中begin(T)和end(T)产生合适的迭代器。

首选和惯用的方法是简单的for循环。

其他方法包括使用整数范围:

template<typename C>
auto container_index(C const& container) -> decltype(boost::irange(0, container.size())) {
  return boost::irange(0, container.size());
}
for(auto x : container_index(xs))

或一个迭代函数:

template<typename F>
void index_iterate(std::size_t size, F func) {
  for(std::size_t i = 0; i != size; ++i) {
    func(i);
  }
}
index_iterate(container.size(), [&](std::size_t i){ /* ... */ });

只要可能就使用简单的循环。

可以组合使用两种方法:

int i = 0;
for ( auto x : v ) {
    // do smth with x or v[i] or i
    i++;
}