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 qualifiersich 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 qualifierssagt 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.