【问题标题】:Remove items from vector, and mutate those which are removed从向量中移除项目,并对移除的项目进行变异
【发布时间】:2014-05-01 22:05:37
【问题描述】:

我有一个std::vector<std::shared_ptr<Foo>>,我想从中erase-remove 匹配某些谓词的项目。被移除的对象应该有一个被调用的方法,该方法设置一些状态以便在其他地方使用。

当返回 true 时,我不应该在谓词函数中这样做吗?感觉有点像混合关注点,但我能想到的唯一选择似乎更难看。

【问题讨论】:

  • 最好总结替代方案,否则您将得到它们作为答案。
  • 我就是这样做的,但是,我能说什么呢,我很懒。没有其他选择仍然允许您使用algorithm 库,对吧?因此,无论哪种方式,您都违反了一些“完美”编程标准的概念。 (编辑:显然有,但我仍然很想按照你的方式去做!)
  • 这是我能想到的最有效的方法。

标签: c++ c++11 erase-remove-idiom


【解决方案1】:

这可能不是一个好主意有两个原因。

首先,大多数标准库算法不应该使用谓词来修改它们所作用的元素。

第二,std::removestd::remove_if 不会给你很好的“移除”元素集*。您只能依赖选择保留的元素。 “删除”的元素实际上可能是“好”元素的副本。而且由于您存储的是共享指针,它们可能指向与“好”元素相同的对象。

另一种方法是使用std::partition,然后遍历分区的相关部分,然后以类似于擦除删除习惯用法的方式使用erase

auto p = std::partition(v.begin, v.end(), pred);
std::for_each(p, v.end(), call_method_functor);
v.erase(p, v.end());

* 这些算法可能应该被命名为keepkeep_if

【讨论】:

  • 这是一个很好的解决方案,但我不太了解这部分:“std::remove... 并没有为您提供一组好的“已删除”元素”。如果您在谓词函数甚至返回之前调用对象上唯一需要的函数,为什么这很重要?
  • @Elliott - 我编写了试图使用“已删除”元素的代码,但我被烧得很厉害。底线是你不应该使用删除的元素,除了擦除。解决方案正是 juanchopanza 在他的回答中提出的,std::partition(或std::stable_partition)。
  • 我喜欢你使用partition 的想法,但是关于remove(_if) 不对已删除元素做出任何保证的部分可能无关紧要,因为OP 声明他将从其他地方对这些对象进行操作.
  • @Praetorian - 这正是我的意思。
  • @DrewNoakes 也许std::stable_partition?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多