std::map::iterator in std::set speichern
-
Hi,
ist so ein Konstrukt erlaubt?
typedef std::map<char, double>Parameter; Parameter parameters; std::set<Parameter::iterator>params;
Hierbei sollen Iteratoren der map
parameters
in dem set gespeichert werden.Denn beim Komplieren bekomme ich den Fehler
Fehler C2678 Binärer Operator "<": Es konnte kein Operator gefunden werden, der einen linksseitigen Operanden vom Typ "const std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>" akzeptiert (oder keine geeignete Konvertierung möglich)
trotz des das ein solcher Operator definiert ist
bool operator <(const Parameter::iterator &rhs, const Parameter::iterator &lhs) { if (rhs->first < lhs->first) return true; else return false; }
Wo liegt jetzt mein Fehler?
-
Iteratoren zu speichern ist ungünstig, da iteratoren auch invalid werden können, wenn sich etwas am entsprechenden container was ändert
-
axels. schrieb:
ist so ein Konstrukt erlaubt?
typedef std::map<char, double>Parameter; Parameter parameters; std::set<Parameter::iterator>params;
...
Denn beim Komplieren bekomme ich den FehlerFehler C2678 Binärer Operator "<": Es konnte kein Operator gefunden werden,...
trotz des das ein solcher Operator definiert ist
bool operator <(const Parameter::iterator &rhs, const Parameter::iterator &lhs) { if (rhs->first < lhs->first) return true; else return false; }
Der Komparator, den std::set benutzt, ist nicht der < Operator selbst, sondern std::lessParameter::iterator.
Wie sieht std::less aus? Im Prinzip so:namespace std { template <class T = void> struct less { constexpr bool operator()(const T& x, const T& y) const { return x < y; } }; }
Wo liegt das Problem?
less liegt im Namensraum std. D.h. bei der unqualifizierten Suche nach einer passenden Überladung des < Operators, wird auch in diesem Namensraum angefangen. Und da die Standardbibliothek den < Operator für diverse Typen überlädt, werden auch einige Kandidaten gefunden. Diese Kandidaten verhindern, dass die unqualifizierte Suche im globalen Namensraum, in dem sich dein Operator vermutlich befindet, forgesetzt wird: die Deklarationen im Namensraum std verdecken die im globalen Namensraum.
ADL kann den globalen Namensraum ebenfalls nicht durchsuchen, denn std::map<char, double>::iterator ist offensichtlich nur mit der Klasse std::map<char, double> und dem Namensraum std assoziert.Welche mögliche Abhilfe besteht?
1. Verschieben des < Operators in den Namensraum std. = nach Standard verboten
2. Spezialisieren von std::less für std::map<char, double>::iterator = ebenfalls nach Standard verboten, da kein UDT involviert ist
3. Benutzung eines eigen Komparators und Verwendung mit std::set:struct my_less { template <typename T> constexpr bool operator()(const T& x, const T& y) const { return x < y; } };
(im selben Namensraum, in dem sich auch deine < Operatorfunktion befindet).
std::set<Parameter::iterator, my_less> params;
-
Danke für die ausführliche Antwort! Hat mir sehr geholfen!