2013-04-27 50 views
7

下面的代碼:爲什麼std :: remove不能用於std :: set?

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

爲什麼兩個定義都不變?爲什麼我的(非常簡單的)代碼不起作用?

+0

你想做什麼?要刪除單個元素只需使用擦除http://www.cplusplus.com/reference/set/set/erase/ – marcadian 2013-04-27 22:36:25

+3

名稱中有一個技巧:'remove'不會刪除元素。它將它們移動到範圍的末尾。對於有序的容器來說,這是完全不可能的。 – pmr 2013-04-27 22:43:24

+0

@marcadian這只是一個例子來說明我的問題。我真正的問題涉及更多的代碼,使用'remove_if'和謂詞,但問題是一樣的。 – 2013-04-27 22:49:23

回答

14

std::set是有序的容器,而std::remove改變容器載置的元件的元件應該被移除以結束,因此它不能與有序的容器,其中元件順序由謂詞所定義可以使用的順序。您需要使用:

s.erase(1); 

從set中刪除1。

相關問題