compare predikat für eine map initialisierung compiliert nicht wenn die argumente const referenzen sind
-
Fehler Nummer 1: Du musst deine get_member-Funktionen als const deklarieren, sonst sieht das so aus, als würden die etwas an NamespaceTest ändern können, wodurch sie auf einem konstanten Objekt disqualifiziert sind. Also
class NamespaceTest { public: NamespaceTest(int, double); int get_member() const; double get_member2() const; private: int member; double member2; }; [...] int NamespaceTest::get_member() const { return member; } double NamespaceTest::get_member2() const{ return member2; }
Fehler 2 ist etwas komplizierter. So wie du das schreibst, kann sich der Compiler nicht zurecht reimen, dass das der Comparator sein soll. Du musst in der Templateliste angeben, welchen Typ dein Comparator haben soll, dann merkt er auch wenn du einen Comparator zu übergeben versuchst. Zum Beispiel:
std::map<NamespaceTest, int, bool(*)(const NamespaceTest&, const NamespaceTest&)> name_vec{compare_predicate};
(es gibt auch andere Varianten davon, aber ich mache es mal so explizit wie möglich)
Ab C++17 könnte man auch CTAD benutzen, aber das ist auch nicht der Weisheit letzter Schluss, weil es sehr alles oder nichts ist. Das ist bei einer Map oft ungünstig, denn man müsste einen Inhalt für den Anfang angeben (damit die Inhaltstypen erschlossen werden können), aber oft will man Maps zu Beginn leer haben.
-
Danke für eure Antworten, sehr hilfreich. Und was ist, wenn ich die Variablen von
get_member()
nicht konstant haben will, weil man sie eben doch ändern kann, aber in dem comparator sollen sie nicht geändert werden, also sollte da
const NamespaceTest& a, ...
stehen. Aber das geht nicht oder?
-
Nein, das geht nicht, denn dann würden ja die Vergleiche, welche die Map durchführt, die Werte in der Map ändern, und die ganze Logik bricht in sich zusammen.
Aber ich bin ziemlich sicher, dass du stattdessen komplett missverstehst, was die const-Qualifizierung an den Funktionen macht.
class X { int get_member() const; };
macht überhaupt keine Aussage über die const'ness der Member von X. Es heißt nur, dass speziell die Funktion
get_member
nichts an den Werten verändern darf.
-
Reine Getter sollten immer konstant sein.
Wenn du doch mal Member innerhalb von konstanten Funktionen ändern willst (z.B. wenn Caching o.ä. benutzt wird), dann kannst du diese als mutable deklarieren.
-
Da muss man aber wirklich, wirklich verstehen, was man tut, bevor man etwas mit
mutable
in einen assoziativen Container wirft. Bloß nicht zuhause nachmachen, bloß um Code zum compilieren zu bekommen, der (zurecht) nicht compilieren will!
-
@fairy2211 sagte in compare predikat für eine map initialisierung compiliert nicht wenn die argumente const referenzen sind:
#include "NamespaceTest.h"
Vertue ich mich, oder ist hier die Konvention "hpp"?
-
@sepe sagte in compare predikat für eine map initialisierung compiliert nicht wenn die argumente const referenzen sind:
@fairy2211 sagte in compare predikat für eine map initialisierung compiliert nicht wenn die argumente const referenzen sind:
#include "NamespaceTest.h"
Vertue ich mich, oder ist hier die Konvention "hpp"?
Wenn du fragst, ob du dich vertust, ist die Antwort doch schon klar, oder?
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rl-file-suffix
-
and it’s easier to name all headers .h instead of having different extensions for just those headers that are intended to be shared with C.
Sorry, aber das ist für mich kein Argument dafür, um unsauber zu arbeiten. Und gewisse C++-Koryphäen widersprechen auch.
Was, wenn ein Architekt sagen würde, jo, eine Hundehütte genügt ja auch und ist einfacher zu bauen? Glaube, das würde keinem gefallen, der keine Hundehütte braucht.
-
@sepe Du hast nach Konvention gefragt. Wenn die C++ Core Guidlines was anderes nutzen ist es unwahrscheinlich, dass das eine Konvention ist, an die man sich halten müsste, oder?
-
@Schlangenmensch sagte in compare predikat für eine map initialisierung compiliert nicht wenn die argumente const referenzen sind:
@sepe Du hast nach Konvention gefragt. Wenn die C++ Core Guidlines was anderes nutzen ist es unwahrscheinlich, dass das eine Konvention ist, an die man sich halten müsste, oder?
Bloß zur Info: sepe ist cyborg_beta, omggg, oder wie er sonst noch so hieß. Damit du nicht zu viel Zeit verschwendest mit gut gemeinten Antworten auf Getrolle.
-
Offenbar gibt es da keine eindeutige Definition/Konvention, an die man sich halten soll.