【问题标题】:GCC Tree STL data containers [duplicate]GCC Tree STL 数据容器 [重复]
【发布时间】:2010-09-23 05:53:21
【问题描述】:

可能重复:
remove_if equivalent for std::map

昨天我写了一个程序,它使用 multiset 来存储这样的元素:

std::multiset < boost::shared_ptr < CEntity > > m_Entities;

然后我尝试像这样使用标准算法remove_if:

std::remove_if(m_Entities.begin, m_Entities.end(), MarkedForDestroy);

但是编译失败,因为如果我们在 GCC 4.4 中看到 set 和 multiset 的实现,我们会看到:

typedef typename _Rep_type::const_iterator            iterator;
typedef typename _Rep_type::const_iterator            const_iterator;

我很震惊。我用谷歌搜索了这一刻,发现这与标准并不矛盾。 set 也是一样。

如果标准算法不起作用,这怎么能矛盾?如何更好地更换容器?

【问题讨论】:

标签: c++ gcc stl set multiset


【解决方案1】:

您不能在关联容器上使用std::remove_if 算法。您需要编写一个for 循环并使用erase 方法删除元素。有关详细信息,请参阅此类似问题 remove_if equivalent for std::map。

【讨论】:

  • 谢谢,这比以前的答案好。
【解决方案2】:

所有标准的有序/关联容器(map、set、multimap、multiset)都有不可变的键(只是键而不是整个容器)。

至于为什么每次更改键的值时只查看需要发生的事情:键类型需要以某种方式通知它的容器它已更改(这会在两者之间引入非常紧密且不必要的耦合容器&它是关键类型——更不用说对于基本类型是不可能的了)因为需要使用容器来保持它的排序属性(这是一个相当大的开销)。

【讨论】:

    【解决方案3】:

    因为multiset(也是set)是不可变容器,即容器中的元素不能changed修改就地,它们可以被删除、修改和(重新)插入。

    参见,例如:

    • 不同的set 相关答案
    • tutorial 中的第 27.3.2.1 节

    在简单的关联容器中, 其中元素是键, 元素是完全不可变的;这 嵌套类型迭代器和 因此 const_iterator 是相同的。

    【讨论】:

    • 我明白这一点。为什么会这样?设置有命令,为什么会出现这样的问题?
    • 不,他们是not。
    • @den bardadym:请注意,remove_if 实际上并没有从容器中“删除”元素,它只是将元素移动到容器的末尾。对于移动到末尾的顺序容器是有意义的,但对于元素按排序顺序存储的关联容器,这没有意义,因为它会破坏它们的顺序。
    • @Matthew Flaschen:我知道元素可以在集合中插入,当我说“元素不能被修改”时,我并没有限制。我的意思是元素不能就地修改。那是因为在 [multi]set 中,元素本身就是底层 BST 的键,如果键被修改,BST 可能不再是 BST。
    • @naveen:谢谢,我不知道。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    • 2018-01-01
    • 2013-01-22
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多