【发布时间】:2012-07-20 03:23:38
【问题描述】:
我一直在阅读最新的 C++ 规范,但我无法确定是否可以为同一元素多次调用 remove_if。特别是,我正在查看 std::remove_if 在 deque 迭代器上被调用。据我所知,如果它所做的只是从第一个参数开始并一直迭代到第二个,则没有理由多次调用它。
我正在处理的代码使用手动引用计数,因此,如果 remove_if 谓词返回 true,它将递减并删除底层对象引用。明显的问题是,这仅在 remove_if 谓词只为每个元素调用一次时才有效,否则后续调用将访问已删除的对象。有些事情告诉我,这并不能保证没问题,并且会出现相同的元素将被传递给 remove_if 谓词两次,用于单个 remove_if 调用。
如果您有某种实现迭代器的疯狂数据结构,并且说,为每个迭代器增量随机选择一个条目,直到它(随机)到达结束迭代器,我可以看到这将如何失败。但是对于像deque、vector 和list 这样的直接标准化结构,单个元素可以多次传递给谓词吗?
【问题讨论】:
-
不是您所问问题的答案,而是您的问题:
§25.1[algorithms.general]/8-- "... 函数对象 pred 不应通过以下方式应用任何非常量函数取消引用的迭代器。” -
请注意,
remove(_if)不会杀死元素,它只会将元素从末尾移动到它们的位置。之后您必须使用擦除删除习惯用法erase他们:cont.erase(std::remove_if(...), cont.end());,这就是它的工作原理。如果你真的需要你的谓词来修改引用计数器,那么你就做错了,并且没有遵守RAII principle。 -
@Xeo 是的。处理某人代码中的一些奇怪限制,基本上我所拥有的只是作为回调提供给库的谓词。本杰明的回答让我怀疑这种方法。
-
由于通知而再次看到这个,我认为非常量函数的限制不是问题。例如,减少引用计数绝对是一个“恒定”的复杂性,甚至调用 free/delete 也可能是,这取决于实现。我必须说,这是一个奇怪的约束。用户代码通常没有复杂性限制。
标签: c++ stl iterator deque remove-if