我需要遍历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';
}
}
答案 0 :(得分:6)
std::list::iterator
是BidirectionalIterator。您可以使用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';
}
答案 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';
}