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