set + remove() + g++ = compiler error



  • Hallo zusammen!
    Normalerweise stell ich mich ja bei Compiler-Fehlern nicht so blöd an, aber bei diesem komm' ich wirklich nicht dahinter, warum...; ich hab ein kleines Programm zusammengestellt, bei dem der Fehler auch auftritt:

    #include <set>
    #include <algorithm>
    
    struct A { int a; };
    bool operator==(A const & left, A const & right) { return left.a == right.a; }
    bool operator< (A const & left, A const & right) { return left.a <  right.a; }
    
    int main()
    {
       std::set<A> s;
       A a = { 0 };
    
       s.insert(a);
       std::remove(s.begin(), s.end(), a);
    
       return 0;
    }
    

    führt zu:

    /usr/include/c++/4.1.3/bits/stl_algo.h: In function ‘_OutputIterator std::remove_copy(_InputIterator, _InputIterator, _OutputIterator, const _Tp&) [with _InputIterator = std::_Rb_tree_const_iterator<A>, _OutputIterator = std::_Rb_tree_const_iterator<A>, _Tp = A]’:
    /usr/include/c++/4.1.3/bits/stl_algo.h:1256:   instantiated from ‘_ForwardIterator std::remove(_ForwardIterator, _ForwardIterator, const _Tp&) [with _ForwardIterator = std::_Rb_tree_const_iterator<A>, _Tp = A]’
    test.cpp:14:   instantiated from here
    /usr/include/c++/4.1.3/bits/stl_algo.h:1181: error: passing ‘const A’ as ‘this’ argument of ‘A& A::operator=(const A&)’ discards qualifiers
    

    ich versteh's nicht...



  • set-Elemente können nur gelesen werden (auf die Weise wird sichergestellt, daß du die interne Sortierung nicht durcheinanderbringst) - und darum kannst du auch keine schreibenden Algorithmen (remove() löscht nicht physikalisch, sondern schichtet die Werte nur um) auf eine set<> loslassen. Stattdessen solltest du set::erase() verwenden.

    (PS: Das ist kein Problem des G++, sondern absolut standardkonform)



  • oh mann, darauf hätte ich auch selbst kommen können (ist eigentlich logisch)...
    vielen dank für die schnelle antwort!

    alles klar, also einfach .find() + .erase()

    PS: ich habe auch nicht geglaubt, es sei ein g++-Problem (ein nicht so standardkonformer compiler hatte das aber übrigens so akzeptiert).



  • error: passing ‘const A’ as ‘this’ argument of ‘A& A::operator=(const A&)’ discards qualifiers
    

    sagt es ja auch schon: Du wendest A::operator= bei einem const A an, versuchst also, einem Konstanten Wert einen neuen Wert zuzuweisen.
    Das ganze wird aufgerufen von std::remove_copy(), welcher wiederum von std::remove() aufgerufen wird, wie die beiden anderen Zeilen sagen.


Anmelden zum Antworten