2013-04-27 3 views
7

다음 코드 : GCC 4.7.2로 컴파일되지 않습니다std :: set에서 std :: remove가 작동하지 않는 이유는 무엇입니까?

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

는 :

$ 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; 

두 정의가 모두 일정한 이유는 무엇입니까? 내 (아주 간단한) 코드가 작동하지 않는 이유는 무엇입니까?

+0

무엇을하려고합니까? 하나의 요소를 삭제하려면 지우개를 사용하십시오 http://www.cplusplus.com/reference/set/set/erase/ – marcadian

+3

이름에 트릭이 있습니다 :'remove'는 요소를 제거하지 않습니다. 범위 끝까지 이동합니다. 이것은 주문한 용기로는 절대 불가능합니다. – pmr

+0

@marcadian 이것은 내 문제를 설명하기위한 예일뿐입니다. 내 진짜 문제는'remove_if'와 술어로 더 많은 코드를 포함하지만 문제는 같습니다. –

답변

14

std::set은 순서가있는 컨테이너이고, std::remove은 끝까지 제거해야하는 컨테이너 배치 요소의 요소 순서를 변경하므로 요소 순서가 술어에 의해 정의 된 순서가 지정된 컨테이너와 함께 사용할 수 없습니다. 다음을 사용해야합니다 :

s.erase(1); 

집합에서 1 개를 제거하려면.