假设我有一个单链表std::forward_list
。我想找到一个匹配谓词的单个列表元素,对它执行一些操作,并根据另一个谓词选择删除它。
到目前为止,我已经汇总了以下内容:
for (T::iterator it = l.begin(), prev_it = l.before_begin();
it != l.end();)
{
if (predicate)
{
// ...
if (another_predicate)
{
l.erase_after(prev_it);
break;
}
}
prev_it = it;
++it;
}
但是,我特别想知道它是否是执行增量部分的最佳方式。或者,我一直在考虑:
++prev_it;
++it;
虽然在简单的C中,前者显然会更好,但在C ++中似乎不再那么清楚了。我相信使用更简单的迭代器,前者应该更简单;但是,如果复制迭代器可能涉及内存分配(例如使用PImpl时),后者可能实际上更好。
您认为哪种方法更优越,为什么?请注意,我希望避免将其严格限制在常见的std::forward_list
设计中,并考虑一种适用于更复杂类型的解决方案。
答案 0 :(得分:3)
当for-loops没有递增计数器时,我感到非常困惑,因此我只需将++prev_it, ++it
添加到你的for循环中。你的迭代器将保持同步状态(假如你不要弄乱它们)并且名称清楚地说明了它们所指的内容。在担心表现之前,我总是站在清晰的一边。
您可能不应该担心将此代码推广到其他容器,因为std::forward_list
是一种特殊情况。其他容器不需要erase_after
等内容。
答案 1 :(得分:2)
如果你用两个增量而不是明显的assign-then-increment来编写它,你所有未来的维护者都会盯着代码一段时间,想知道它们缺少什么以及为什么以这种方式编写。
你应该以显而易见的方式编写代码(保存prev,然后增加),如果你的迭代器复制成本很高,分析表明它是一个问题,找一个更好的迭代器。您通常不应该像这样进行代码更改,以解决可能甚至不会显着影响您的性能的问题。
编辑:正如@Kerrek SB在对该问题的评论中指出的那样,并且您满足于略微说明您的意思,您可以使用forward_list::remove_if
和(小心)有状态谓词来实现这一点。