我目前有以下for循环:
for(list<string>::iterator jt=it->begin(); jt!=it->end()-1; jt++)
我有一个字符串列表,列在一个更大的列表中(list<list<string> >
)。我想循环遍历内部列表的内容,直到我到达倒数第二个元素。这是因为我已经处理了最终元素的内容,没有理由再次处理它们。
但是,使用it->end()-1
无效 - 我无法在此处使用-
运算符。虽然我可以使用--
运算符,但这会在每个循环中减少这个最终迭代器。
我认为STL列表是一个双向链表,所以从我的角度来看,应该可以这样做。
么?提前致谢
答案 0 :(得分:8)
使用标准库的必要建议:
std::for_each(lst.begin(), --lst.end(), process);
如果您不想为创建一个仿函数[我几乎从不这样做]而烦恼,并且您不能使用反向迭代器,那么将结束检查提升出来:
for(iterator i = lst.begin(), j = --lst.end(); i != j; ++i) {
// do
// stuff
}
或者,您可以信任优化器,以确认它不必继续重新创建结束条件,并自行吊装。这有多可靠取决于列表实现,循环代码的复杂程度以及优化程序的优异程度。
无论如何,只要做最容易理解的事情,并在完成后担心性能。
答案 1 :(得分:6)
列表迭代器不是随机迭代器。您应该执行以下操作:
if ( ! it->empty() )
{
list<string>::iterator test = it->end();
--test;
for( list<string>::iterator jt = it->begin(); jt != test; ++jt )
{
...
}
}
还有一件事:对++jt
使用jt++
。 jt++
源代码通常如下所示:
iterator operator++ (int i)
{
iterator temp = (*this);
++(*this);
return temp;
};
答案 2 :(得分:4)
不,它不会。它将获得结束迭代器的副本并减少它。就这样。它不会更改列表中存储的结束迭代器。虽然我可以使用 - 运算符,但这会在每个循环中减少这个最终迭代器。
您的主要问题应该是验证列表不为空,从而确保--it-&gt; end()存在。
答案 3 :(得分:4)
反向迭代器怎么样?
for(list<string>::reverse_iterator jt=++(it->rbegin()); jt!=it->rend(); jt++)
答案 4 :(得分:4)
在c ++ 11及更高版本中,最佳答案似乎是使用std::prev
for(iterator i = lst.begin(); i != std::prev(lst.end()); ++i) {
// do
// stuff
}
http://en.cppreference.com/w/cpp/iterator/prev上std :: prev的文档说明,
尽管表达式--c.end()经常编译,但不保证这样做:c.end()是一个右值表达式,并且没有迭代器要求指定rvalue的减量保证工作。特别是,当迭代器实现为指针时, - c.end()不会编译,而std :: prev(c.end())会执行。
我相信空列表中的std :: prev()是未定义的,因此您可能需要将其包装在!i.empty()
条件