Suchen mit Zeiger auf Konstante in einer map
-
std::map<const Objekt *, value> MeineMap;
-
const_cast?
Das wäre nicht gut...
-
coder777 schrieb:
const_cast?
Das wäre nicht gut...
Wieso? Dein Programm ist sowieso nicht const-sicher, da du mit find Zugriff auf den Key erhältst (und der ist nicht const).
-
Wieso? Dein Programm ist sowieso nicht const-sicher, da du mit find Zugriff auf den Key erhältst (und der ist nicht const).
Das übergebene Objekt muss sich aber nicht notwendiger Weise in der map befinden.
Es ist so, dass sich die map in einer Klasse befindet.
Intern darf die Klasse die Objekte änderen (und andere Klassen darüber informieren).
Extern darf sich aber nichts ohne Einbeziehung der Klasse änderen.
Den Schlüssel konstant zu machen ist leider keine Alternative.Das einzige Problem ist, dass ich den Zeiger auf das konstante Objekt der find(...) Funktion nicht übergeben kann. Vergleichsoperatoren würden ja funktionieren.
Keine Alternativen zu const_cast?
-
Mit C++14 kannst du es mit std::less<> als Vergleichsoperator machen. Ich weise allerdings nochmal darauf hin, dass das eine schlechte Idee ist und nicht besser als ein const_cast.
Es ist so, dass sich die map in einer Klasse befindet.
Intern darf die Klasse die Objekte änderen (und andere Klassen darüber informieren).
Extern darf sich aber nichts ohne Einbeziehung der Klasse änderen.Perfekt, dann mach die map privat und biete Zugriffsfunktionen an, die sich schön um const-correctness kümmern.
-
cccc schrieb:
Mit C++14 kannst du es mit std::less<> als Vergleichsoperator machen.
Nicht das ich das vor hätte, aber was genau meinst du?
std::less<>als dritten Template Parameter für die map oder was? Das ist hilft jedenfalls nicht, da schon die Signatur vonstd::map::findkonstante Pointer ablehnt.Mir würde sonst noch das hier einfallen (auch nicht unbedingt leserlicher als der
const_cast).const Objekt *SucheObjekt(const Objekt *MeinObject) { std::map<Objekt *, value>::const_iterator it = std::find_if(MeineMap.begin(), MeineMap.end(), [&](const auto &p) { return p.first == MeinObject; }); }
-
Nachtrag: Und vor allem ist es langsamer, da
std::find_ifüber alle Keys iteriert.
-
sebi707 schrieb:
cccc schrieb:
Mit C++14 kannst du es mit std::less<> als Vergleichsoperator machen.
Nicht das ich das vor hätte, aber was genau meinst du?
std::less<>als dritten Template Parameter für die map oder was?Ja.
std::map<int *, int, std::less<>> MeineMap; int i = 0; auto const *p = &i; auto it = MeineMap.find(p);Funktioniert, weil
std::less<>einen Membertypis_transparenthat und die map dadurch eine neue Überladung anbietet.
-
Ah interessant. Das ist aber schon ein ziemlich neues Feature... Die STL Version, welche mit gcc 4.9 kommt hat das noch nicht drin.
-
Die C++14 Erweiterung ist schon genau das was ich brauche. Nur ist C++14 noch nicht richtig angekommen. Ich verstehe das is_transparent auch nicht so richtig.
Ich habe jetzt erst einmal const_cast benutzt.
cccc schrieb:
Perfekt, dann mach die map privat und biete Zugriffsfunktionen an, die sich schön um const-correctness kümmern.
Genauso habe ich das auch gemacht.
-
coder777 schrieb:
Ich verstehe das is_transparent auch nicht so richtig.
Das ist mal wieder Template Zeug. Wenn ein Comparator vergleiche mit beliebigen Typen unterstützt, dann soll dieser das eben bekannt machen indem es ein typedef für
is_transparentdefiniert. Für welchen Typ das typedef ist ist dabei völlig egal, wichtig ist nur, dass es existiert. Denn dann kann eine Klasse wie z.B.std::mapprüfen ob dieses typedef existiert und nur dann zusätzlichefindFunktionen anbieten (Stichwort zum googeln: SFINAE).