C++ GCC树STL数据容器
可能重复:C++ GCC树STL数据容器,c++,gcc,stl,set,multiset,C++,Gcc,Stl,Set,Multiset,可能重复: 昨天我写了一个程序,它使用multiset存储如下元素: std::multiset < boost::shared_ptr < CEntity > > m_Entities; std::remove_if(m_Entities.begin, m_Entities.end(), MarkedForDestroy); 但是编译失败了,因为如果我们在GCC 4.4中看到set和multiset的实现,我们会看到: typedef typename _Rep_
昨天我写了一个程序,它使用multiset存储如下元素:
std::multiset < boost::shared_ptr < CEntity > > m_Entities;
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;
我很震惊。我搜索了这一刻,发现这与标准并不矛盾,这是更好的。布景也一样
如果标准算法不起作用,这怎么会矛盾呢?如何更好地更改容器?因为multiset(以及set)是不可变的容器,即容器中的元素不能就地更改、修改,可以删除、修改和(重新)插入
例如,见:
- 另一个相关的答案
- 本规范第27.3.2.1节
如果关联容器上有
算法,则不能使用std::remove\u。您需要为
循环编写一个,并使用擦除
方法删除元素。有关更多详细信息,请参见此类似问题。所有标准有序/关联容器(映射、集合、多重映射、多重集)都有不可变的键(仅键而不是整个容器)
至于为什么每次更改密钥的值时都要看会发生什么:密钥类型需要以某种方式通知其容器它已更改(这将在容器和密钥类型之间引入非常紧密和不必要的耦合-更不用说对于基本类型是不可能做到的)因为需要重新调用容器以保持其ordering属性(这是一个相当大的开销) 我明白这一点。为什么会这样?Set有一个顺序,为什么会出现这样的问题?不,它们是。@den bardadym:请注意,remove\u如果
实际上没有从容器中“删除”元素,它只是将元素移动到容器的末尾。对于顺序容器移到末尾是有意义的,但是对于元素按排序顺序存储的关联容器,这没有意义,因为它会破坏它们的顺序。@Matthew Flaschen:我知道元素可以插入到集合中,我没有限制这一点,当我说“元素不能修改”时。我的意思是元素不能就地修改。这是因为在[multi]集合中,元素本身就是基础BST的键,如果这些键被修改,BST可能不再是BST。@naveen:谢谢,我不知道。谢谢,这比前面的答案要好。