问题描述
|
我目前有以下for循环:
for(list<string>::iterator jt=it->begin(); jt!=it->end()-1; jt++)
我有一个较大的字符串列表(list<list<string> >
)。我想遍历内部列表的内容,直到到达倒数第二个元素为止。这是因为我已经处理了final元素的内容,并且没有理由再次处理它们。
但是,使用it->end()-1
无效-我不能在这里使用-
运算符。虽然我可以使用--
运算符,但这会减少每个循环的最终迭代器。
我相信STL列表是一个双向链接列表,因此从我的角度来看,应该可以做到这一点。
忠告?提前致谢
解决方法
使用标准库的必要建议:
std::for_each(lst.begin(),--lst.end(),process);
如果您不想麻烦地创建函子[我几乎从不这样做],并且您不能使用反向迭代器,请结束循环进行结帐:
for(iterator i = lst.begin(),j = --lst.end(); i != j; ++i) {
// do
// stuff
}
或者,您可以信任优化器来识别它不必继续创建最终条件,而是自己进行提升。这是否可靠取决于列表实现,循环代码的复杂程度以及优化器的性能。
无论如何,只要做最容易理解的事情,并在完成后担心性能。
, 列表迭代器不是随机迭代器。您应该执行以下操作:
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;
};
,
虽然我可以使用-运算符,但这会使每个循环的最终迭代器递减。
不,不会。它将获得最终迭代器的副本并将其递减。就这样。它不会更改列表中存储的最终迭代器。
您的主要问题应该是验证列表是否为空,从而确保--it-> end()存在。
, 反向迭代器呢?
for(list<string>::reverse_iterator jt=++(it->rbegin()); jt!=it->rend(); jt++)
, 在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()是一个右值表达式,并且没有迭代器要求指定保证右值递减可以正常工作。特别是,当迭代器实现为指针时,--c.end()不会编译,而std :: prev(c.end())会编译。
我相信空列表上的std :: prev()是未定义的,因此您可能需要将其包装为!i.empty()
条件