【问题标题】:remove_if without the need of move and copy semanticsremove_if 不需要移动和复制语义
【发布时间】:2020-07-28 08:16:12
【问题描述】:

这是典型的矢量删除-擦除操作的样子:

auto toErase = std::remove_if(vec.begin(), vec.end(),
   [val](obj_t const& obj) { return obj.myval == val; }
); // This actually moves objects around !

vec.erase(toErase, vec.end()); 

这在大多数情况下都可以正常工作,但我遇到了obj_t 类型不允许移动或复制语义的情况。使用vec.emplace_back() 插入对象,我正在寻找不需要复制或移动的remove_if 的替代方法。

它是否已经存在于某个地方?如果没有,怎么建?

【问题讨论】:

  • 那么向量可能不适合您?即使使用emplace_back,向量也可能需要重新分配其数据,这意味着移动/复制对象。
  • 请注意,remove_if 除了移动/复制元素之外什么都不做。 (如果你 erase 位于向量末尾以外的任何地方,则必须再次移动/复制元素)

标签: c++ algorithm vector move-semantics c++-standard-library


【解决方案1】:

如果对象是不可移动/可复制的,您希望如何重新排列向量中的对象? Vector 是一个连续的容器 - 所以你不能在不改变结尾的情况下擦除中间的元素。

要解决此问题,要么使对象可移动/可复制,将其包装在 unique_ptr 中(从而使其可移动),或者使用 map/set/unordered_map 容器之一,因为这些容器不会像 std::vector 那样重新定位对象

【讨论】:

  • 实际上std::list 可能是std::vector 比关联容器更好的替代品。
  • 如何在不移动的情况下从std::list 中删除-擦除?
  • 我找到了!使用std::list::remove_if( lambda )
  • @rustyx 我不喜欢std::list,因为它缺乏任何形式的查找。使用非常有限。但我想有时不需要其他任何东西。
【解决方案2】:

如果没有复制或移动支持,就无法从std::vector 中删除:当您从中间删除某些内容时,您将如何处理大小写?例如,您可以使用 std::list<Class>std::vector<std::shared_ptr<Class>> 代替 std::vector<Class>

其实如果主要问题围绕remove_if:我推荐你使用shared_ptr或者unique_ptr

【讨论】:

  • 挑剔:你把事情搞混了。算法语音中的“删除”实际上并没有删除任何内容。它只会重新排列容器中的元素。
猜你喜欢
  • 2018-09-17
  • 2013-10-17
  • 2013-11-05
  • 1970-01-01
  • 2017-09-08
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
相关资源
最近更新 更多