遍历列表容器(不包括最后一个元素)

时间:2018-07-25 03:20:35

标签: c++ c++11 c++14

我需要遍历std::list直到end() - 1(因此遍历时,我不想包括最后一个元素)。什么是有效的方法?

#include <iostream>
#include <list>
using namespace std;

int main()
{
    list<int> l{1,2,3,4,5};

    for(auto itr = l.begin(); itr != l.end() - 1; ++itr)
    {   
        cout << *itr << '\n';
    }   
}

4 个答案:

答案 0 :(得分:6)

std::list::iteratorBidirectionalIterator。您可以使用std::prev来获取需要停止的迭代器。

for(auto itr = l.begin(), end = std::prev(l.end()); itr != end; ++itr)
{
   ...
}

查看它在https://ideone.com/26lJSC上的运行情况。

答案 1 :(得分:1)

无论迭代器是双向的还是非双向的,代码都将如下所示:

for (auto itr2 = l.begin(), itr = l.end(); itr2 != l.end(); itr = itr2, ++itr2) {
    if (itr != l.end()) {
        cout << *itr << '\n';
    }
}

答案 2 :(得分:1)

使用range-v3,它将是:

for (auto e : l | ranges::view::take(l.size() - 1))
{
    std::cout << e << '\n';
}

Demo

答案 3 :(得分:0)

就个人而言,对于也可用于单向迭代器的代码,我将使用高级迭代器,尽管如果列表为空,则存在初始化的复杂性:

for (it = l.begin(), ite = l.end(), itA = (it==ite)?it:std::next(it); itA != ite; it = itA, ++itA)
{
    std::cout << e << '\n';
}

我们正在为每次迭代制作一个额外的副本,编译器可能会对其进行一些优化。它不能对比较做很多事情。

为了简洁起见,您可以将增量放在比较中,并且知道时列表不是空的,但是我发现非常不可读

if (!l.empty())
  for (it = l.begin(), ite = l.end(), itA = it; ++itA != ite; it = itA)
  {
    std::cout << e << '\n';
  }