擦除std :: forward_list中的单个元素 - prev_it = it或++ prev_it?

时间:2012-08-17 17:12:10

标签: c++

假设我有一个单链表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设计中,并考虑一种适用于更复杂类型的解决方案。

2 个答案:

答案 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和(小心)有状态谓词来实现这一点。