Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does std::remove not work with std::set?

Tags:

c++

gcc

stdset

The following code:

#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);
}

does not compile with 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>()'

So I went to the definition of fset::iterator and I've found this in gcc's implementation (file ../c++/4.7/bits/stl_set.h, from 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;

Why are both definitions constant? Why does my (pretty simple) code not work?

like image 871
Peregring-lk Avatar asked Apr 27 '13 22:04

Peregring-lk


People also ask

How to remove std in c++?

std::remove, std::remove_if. Removes all elements satisfying specific criteria from the range [first, last) and returns a past-the-end iterator for the new end of the range. 1) Removes all elements that are equal to value , using operator== to compare them. 3) Removes all elements for which predicate p returns true.

Is std::set ordered C++?

Per the C++ standard, iteration over the elements in an std::set proceeds in sorted order as determined by std::less or by the optional comparison predicate template argument.


1 Answers

std::set is ordered container, while std::remove changes order of elements in container placing elements that should be removed to the end, thus it can't be used with ordered containers where elements order is defined by predicate. You need to use:

s.erase( 1);

To remove 1 from set.

like image 72
alexrider Avatar answered Oct 08 '22 01:10

alexrider