【问题标题】:Why does std::remove not work with std::set?为什么 std::remove 不适用于 std::set?
【发布时间】:2015-05-14 23:45:01
【问题描述】:

以下代码:

#include <iostream>
#include <set>
#include <algorithm>

std::set<int> s;

int main()
{
    s.insert(1);
    s.insert(2);

    std::remove(s.begin(), s.end(), 1);
}

不使用 gcc 4.7.2 编译:

$ LANG=C g++ test.cpp
In file included from /usr/include/c++/4.7/algorithm:63:0,
             from test.cpp:3:
/usr/include/c++/4.7/bits/stl_algo.h: In instantiation of '_FIter std::remove(_FIter, _FIter, const _Tp&) [with _FIter = std::_Rb_tree_const_iterator<int>; _Tp = int]':
test.cpp:12:38:   required from here
/usr/include/c++/4.7/bits/stl_algo.h:1135:13: error: assignment of read-only location '__result.std::_Rb_tree_const_iterator<_Tp>::operator*<int>()'

所以我去了fset::iterator的定义,我在gcc的实现中找到了这个(文件../c++/4.7/bits/stl_set.h,来自125):

  // _GLIBCXX_RESOLVE_LIB_DEFECTS                                                                                                                                                             
  // DR 103. set::iterator is required to be modifiable,                                                                                                                                      
  // but this allows modification of keys.                                                                                                                                                    
  typedef typename _Rep_type::const_iterator            iterator;
  typedef typename _Rep_type::const_iterator            const_iterator;
  typedef typename _Rep_type::const_reverse_iterator    reverse_iterator;
  typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
  typedef typename _Rep_type::size_type                 size_type;
  typedef typename _Rep_type::difference_type           difference_type;

为什么两个定义都是不变的?为什么我的(非常简单的)代码不起作用?

【问题讨论】:

  • 你想做什么?要删除单个元素,只需使用擦除 cplusplus.com/reference/set/set/erase
  • 名称中有一个技巧:remove 不会删除元素。它将它们移动到范围的末端。这对于一个有序的容器是完全不可能的。
  • @marcadian 这只是一个例子来说明我的问题。我真正的问题涉及更多的代码,remove_if 和一个谓词,但问题是一样的。

标签: c++ gcc stdset


【解决方案1】:

std::set 是有序容器,而std::remove 更改容器中元素的顺序,将应该删除的元素放置到最后,因此它不能与元素顺序由谓词定义的有序容器一起使用。你需要使用:

s.erase( 1);

从集合中删除 1。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-21
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 2019-04-26
    相关资源
    最近更新 更多