Anzahl gleicher Elemente mit equal_range berechnen
-
ACnut schrieb:
ah gut zu wissen
das heißt innerhalb der klasse würde die funktion so aussehen?
bool Element:: operator <(const Element& E) { Element blabla(*this); return blabla.ngen < E.ngen; }
Die Qualifizierung mit dem Klassennamen (Element::) musst du weglassen, das muss eine unqualified-id sein.
Die Variante mit der Operatorfunktion als Memberfunktion hat einen Nachteil: Falls die Klasse, für die der Operator überladen wird, einen Konvertierungskonstruktor bereitstellt, kann dieser bei der Deklaration als Member nicht ausgenutzt werden. Komische Semantik:
struct MyClass { int val; MyClass(int val): val(val) {} bool operator<( MyClass const& c ) const { return val < c.val; } }; int main() { if( MyClass(7) < 4 ) // Das geht noch // ... if( 4 < MyClass(4) ) // Wums. Nicht möglich. // ... }
-
das heißt innerhalb der klasse würde die funktion so aussehen?
volkard schrieb:
..
Alles falsch :p
-
Mmm, sicher Sone:
http://ideone.com/xQQE5V
-
Nathan schrieb:
Mmm, sicher Sone:
http://ideone.com/xQQE5VEs ging mir um die Definition in der Klasse http://ideone.com/hiNh2r
-
Sone schrieb:
Nathan schrieb:
Mmm, sicher Sone:
http://ideone.com/xQQE5VEs ging mir um die Definition in der Klasse http://ideone.com/hiNh2r
Und ging es darum, daß die Funktion in der Klasse ist.
-
-
volkard schrieb:
Sone schrieb:
Nathan schrieb:
Mmm, sicher Sone:
http://ideone.com/xQQE5VEs ging mir um die Definition in der Klasse http://ideone.com/hiNh2r
Und ging es darum, daß die Funktion in der Klasse ist.
Naja, ich dachte jetzt, in der Klasse heißt in der Klasse.
Übrigens, wenn du den kleiner-als Operator überlädst, solltest du auch immer direkt den ist-gleich Operator mit überladen. Die kommen meistens im Zweierpack.
bool Element:: operator <(const Element& E) { Element blabla(*this); return blabla.ngen < E.ngen; }
Wieso eine Kopie?
Volkards dritte Lösung ist die gängigste.
-
Sone schrieb:
Übrigens, wenn du den kleiner-als Operator überlädst,
solltest du auch immer direkt den ist-gleich Operator mit überladen.Die kommen meistens im Zweierpack.Wozu? operator< reicht doch immer völlig.
Dazu noch ein kleines Rätsel:
std::cout << std::boolalpha << (x < y || y < x || x == y) << '\n'; // Ausgabe: false
x, y sind dabei von Typen aus reinem C++.
-
lazyprogger schrieb:
Sone schrieb:
Übrigens, wenn du den kleiner-als Operator überlädst,
solltest du auch immer direkt den ist-gleich Operator mit überladen.Die kommen meistens im Zweierpack.Wozu? operator< reicht doch immer völlig.
stl-algos verwenden eigentlich je nach dem, den op< oder den o==. und daraus werden sich die anderen vier gebaut. den op== aus dem op< zu bauen, kann lahm sein.
deshalb sollte man die beiden anbieten.
-
lazyprogger schrieb:
Dazu noch ein kleines Rätsel:
std::cout << std::boolalpha << (x < y || y < x || x == y) << '\n'; // Ausgabe: false
x, y sind dabei von Typen aus reinem C++.
double x=1; double y=log(-1);
-
volkard schrieb:
stl-algos verwenden eigentlich je nach dem, den op< oder den o==. und daraus werden sich die anderen vier gebaut. den op== aus dem op< zu bauen, kann lahm sein.
deshalb sollte man die beiden anbieten.Wenn ich sort will, dann schreibe ich op< und gut ist, für find mach ich op==. Und op== aus op< aufbauen gibt dem Compiler etwas zu tun, aber langsamer ist das schlussendlich nicht. Möglichst alle Operatoren für alle Eventualitäten zu überladen macht den Code auch nicht generischer.
Dass die std-algos op== verwenden ist recht so, weil manchmal kann op< tatsächlich viel lahmer sein, aber das sind dann Spezialfälle.
-
ich sehe zu viele funktionen xD
bin verwirrt
also was ist jetzt richtig?Die Qualifizierung mit dem Klassennamen (Element::) musst du weglassen, das muss eine unqualified-id sein.
wieso geht das? bei anderen methoden muss ich ja das Element:: auch schreiben?
-
lazyprogger schrieb:
Wenn ich sort will, dann schreibe ich op< und gut ist, für find mach ich op==. Und op== aus op< aufbauen gibt dem Compiler etwas zu tun, aber langsamer ist das schlussendlich nicht. Möglichst alle Operatoren für alle Eventualitäten zu überladen macht den Code auch nicht generischer.
Es ist praktisch, wenn man die map einfach so mal durch eine unordered_map austauschen kann. oft genug baue ich aber auch klassen, die echt nur einen brauchen.
lazyprogger schrieb:
Dass die std-algos op== verwenden ist recht so, weil manchmal kann op< tatsächlich viel lahmer sein, aber das sind dann Spezialfälle.
So speziell wie string.
halt, ich meinte nicht, daß der op< lahmer als der op== ist (das ist schon selten), sondern dass a<b||b<a gerne mal lahmer ist als !(a==b).
-
ACnut schrieb:
ich sehe zu viele funktionen xD
bin verwirrt
also was ist jetzt richtig?Welche gefällt Dir denn am besten?
-
bool Element:: operator <(const Element& E) { Element& blabla=*this; return blabla.ngen < E.ngen; }
der sieht schön aus
-
ACnut schrieb:
bool Element:: operator <(const Element& E) { Element& blabla=*this; return blabla.ngen < E.ngen; }
der sieht schön aus
Bleiben die Fragen
- wozu Du noch die Referenzblabla
anlegst und
- was Du noch besser machen koenntest, damit folgendes kompiliert:bool f(const Element& x, const Element& y){ return x<y; }
-
volkard schrieb:
Es ist praktisch, wenn man die map einfach so mal durch eine unordered_map austauschen kann.
Eine Hashfunktion schreibt sich nicht "einfach so".
-
lazyprogger schrieb:
volkard schrieb:
Es ist praktisch, wenn man die map einfach so mal durch eine unordered_map austauschen kann.
Eine Hashfunktion schreibt sich nicht "einfach so".
Für einige Dinge sind Hashfunktionen bereits vorprogrammiert. Und wenn meine Klasse nur aus einigen Skalaren oder Strings besteht, ist es auch nicht so schwer.
-
Sone schrieb:
Für einige Dinge sind Hashfunktionen bereits vorprogrammiert. Und wenn meine Klasse nur aus einigen Skalaren oder Strings besteht, ist es auch nicht so schwer.
Es geht darum, dass der Wechsel von
std::map
zustd::unordered_map
mit dem Vorhandensein desoperator==
nicht getan ist.Man muss in den meisten Fällen
std::hash
spezialisieren -- und falls nicht, ist einoperator==
sehrwahrscheinlich auch schon vorhanden.
-
Furble Wurble schrieb:
ACnut schrieb:
bool Element:: operator <(const Element& E) { Element& blabla=*this; return blabla.ngen < E.ngen; }
der sieht schön aus
Bleiben die Fragen
- wozu Du noch die Referenzblabla
anlegst und
- was Du noch besser machen koenntest, damit folgendes kompiliert:bool f(const Element& x, const Element& y){ return x<y; }
-damit ich keine kopie habe
-wie tu ich das?