C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

ZugrifsKlasse fuer map
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Stephan Menzel
Guest





PostPosted: Mon Mar 21, 2005 5:11 pm    Post subject: ZugrifsKlasse fuer map Reply with quote



Hi,

ich habe hier eine std::map deren Schluesselelement eine eigene Klasse sein
soll. Diversen Kompilerfehlermeldungen entnahm ich, dass diese Klasse
mindestens den operator< und operator== ueberladen muss um als Schluessel
dienen zu koennen. Beides tat ich.
Und es kompiliert auch schoen und ich kann Elemente in die map reintun
(size() zeigt sie auch an) nur rausholen scheine ich sie nicht zu koennen.

map->find() liefert einfach nur end. Unzufriedenstellend. Was koennten da
die Gruende sein? Was muss ich noch beachten bei solch einer
Schluesselklasse?

Die Klasse selber uebrigens besteht im wesentlichen aus einer Reihe von
Werten verschiedener Groesse, die alle gleich sein muessen, wenn == true
liefern soll.
Semantisch kann es einen Ungleichoperator nicht wirklich geben, deswegen
teste ich einfach der Reihe nach durch:


bool Key::operator<(const Key &key2) const {
if(val1 < key2.val1)
return true;
else
if(val1 == key2.val1)
if(val2 < key2.val2)
return true;
else
if (val2 == key2.val2)
if(val3 < key2.val3)
return true;
else
if(val3 == val3)
if(val4 < key2.val4)
return true;
else
....usw...

return false; //uhh yeah! get outta here!
}

Oder ist das etwa flcsha?

Stephan, ein bisschen ratlos aber nicht in die STL reindebuggen wollend
--
Freedom isn't lost in one big step when the storm-troopers
show up at your door. It is lost in little pieces, each
so small that they tend to be ignored.
Richard B. Johnson

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Rolf Magnus
Guest





PostPosted: Mon Mar 21, 2005 6:06 pm    Post subject: Re: ZugrifsKlasse fuer map Reply with quote



Stephan Menzel wrote:

Quote:
Hi,

ich habe hier eine std::map deren Schluesselelement eine eigene Klasse
sein soll. Diversen Kompilerfehlermeldungen entnahm ich, dass diese Klasse
mindestens den operator< und operator== ueberladen muss um als Schluessel
dienen zu koennen.

operator< sollte reichen. Aber auch den brauchst du nicht, falls du der Map
noch ein Prädikat mitgibst.

Quote:
Beides tat ich.
Und es kompiliert auch schoen und ich kann Elemente in die map reintun
(size() zeigt sie auch an) nur rausholen scheine ich sie nicht zu koennen.

Das ist schade. Erinnert mich an dieses tolle Backup-System, das die Daten
per Videorekorder gespeichert hat. Das Backup klappte prima, nur das
Restore nicht ;-)

Quote:
map->find() liefert einfach nur end. Unzufriedenstellend. Was koennten da
die Gruende sein? Was muss ich noch beachten bei solch einer
Schluesselklasse?

Die Klasse selber uebrigens besteht im wesentlichen aus einer Reihe von
Werten verschiedener Groesse, die alle gleich sein muessen, wenn == true
liefern soll.
Semantisch kann es einen Ungleichoperator nicht wirklich geben,

Die Korrektheit dieses Operators ist aber für eine map von entscheidender
Bedeutung. Wenn der Operator nicht stimmt, funktioniert die Map nicht.

Quote:
deswegen teste ich einfach der Reihe nach durch:


bool Key::operator<(const Key &key2) const {
if(val1 < key2.val1)
return true;
else
if(val1 == key2.val1)
if(val2 < key2.val2)
return true;
else
if (val2 == key2.val2)
if(val3 < key2.val3)
return true;
else
if(val3 == val3)

val3 == val3 gilt immer. Ist dieser Fehler auch im Originalprogramm
enthalten?

Quote:
if(val4 < key2.val4)
return true;
else
...usw...

return false; //uhh yeah! get outta here!
}

Oder ist das etwa flcsha?

Stephan, ein bisschen ratlos aber nicht in die STL reindebuggen wollend

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Stephan Menzel
Guest





PostPosted: Mon Mar 21, 2005 6:17 pm    Post subject: Re: ZugrifsKlasse fuer map Reply with quote



Rolf Magnus wrote:

Quote:
operator< sollte reichen. Aber auch den brauchst du nicht, falls du der
Map noch ein Prädikat mitgibst.

Ein Praedikat?
Wie sieht denn das in der Praxis aus? Eine selbetdefinierte Sortieroperation
oder so?

Quote:
Das ist schade. Erinnert mich an dieses tolle Backup-System, das die Daten
per Videorekorder gespeichert hat. Das Backup klappte prima, nur das
Restore nicht Wink

Wink
Genau so ist es.

Quote:
Die Korrektheit dieses Operators ist aber für eine map von entscheidender
Bedeutung. Wenn der Operator nicht stimmt, funktioniert die Map nicht.

So sieht es aus. Weitere Tests zeigten mir gerade, dass der Fehler beim
letzten Element auftritt, welches in die Map kommt. Dieses wird nicht
gefunden. Die anderen schon, und die kann ich auch rausholen.
Bedauerlicherweise weiss ich noch nicht, ob das am Element selber liegt
oder daran, dass es das letzte ist.

Quote:
if (val2 == key2.val2)
if(val3 < key2.val3)
return true;
else
if(val3 == val3)

val3 == val3 gilt immer. Ist dieser Fehler auch im Originalprogramm
enthalten?

Ooops! Nein. Zum Glueck nicht. Nur ein Fehler der beim Simplifizieren
auftrat. Das Original sieht eigentlich gut aus, wenn der Ablauf denn passt.
Weitere Debugausgaben zeigten mir gerade, dass wohl der insert selber
fehlschlaegt. Rufe ich size() nach dem letzten Insert auf, ist ein Element
weniger als erwartet in der map. Ich tendiere dazu anzunehmen, dass einfach
mein operator< falshc ist.

Stephan, weitersuchend
--
Freedom isn't lost in one big step when the storm-troopers
show up at your door. It is lost in little pieces, each
so small that they tend to be ignored.
Richard B. Johnson

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Tobias Güntner
Guest





PostPosted: Mon Mar 21, 2005 7:39 pm    Post subject: Re: ZugrifsKlasse fuer map Reply with quote

Stephan Menzel wrote:
Quote:
bool Key::operator<(const Key &key2) const {
if(val1 < key2.val1)
return true;
else
if(val1 == key2.val1)
if(val2 < key2.val2)
return true;
else
if (val2 == key2.val2)
if(val3 < key2.val3)
return true;
else
if(val3 == val3)
if(val4 < key2.val4)
return true;
else
....usw...


Formatier's doch mal anders, vielleicht löst sich das Problem dann von
selbst.

{
if(val1 < key2.val1)
return true;
if(key2.val1 < val1)
return false;

if(val2 < key2.val2)
return true;
if(key2.val2 < val2)
return false;

....

if(val20 < key2.val20)
return true;
if(key2.val20 < val20)
return false;

return val21 < key2.val21;
}
--
Regards,
Tobias

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Falk Tannhäuser
Guest





PostPosted: Mon Mar 21, 2005 11:16 pm    Post subject: Re: ZugrifsKlasse fuer map Reply with quote

Stephan Menzel wrote:
Quote:
Rolf Magnus wrote:
operator< sollte reichen. Aber auch den brauchst du nicht, falls du der
Map noch ein Prädikat mitgibst.
Ein Praedikat?
Wie sieht denn das in der Praxis aus? Eine selbetdefinierte Sortieroperation
oder so?

In etwa so:
struct CmpKey
{
bool operator()(Key const& a, Key const& b) const
{ /* So wie dein operator< */ }
};

Und wird so benutzt:
std::map
Dies wird dann bevorzugt, wenn die Vergleichsoperation wirklich nur
für den Zweck dient, die Keys in der Map einzuordnen, aber sonst
im Allgemeinen keine sinnige Bedeutung hat. Beispiel: Es sollen
Personen als Schlüsseltyp verwendet werden. Als Vergleichskriterium
könnten dienen: Erst Nachname, dann Vorname, dann Geburtsdatum,
oder auch die Sozialversicherungsnummer, oder die Personalausweisnummer,
oder bei Firmenangestellten das Eintrittsdatum, oder...
Keine dieser Möglichkeiten ist von vornherein "natürlicher" als die
anderen, und es ist i.d.R. auch nicht so wichtig, welche man wählt -
Hauptsache, man benutzt eine einheitliche. Hier wird man aus Gründen
der Klarheit ein Prädikat anstelle eines "operator<" bevorzugen.

Quote:
Das Original sieht eigentlich gut aus, wenn der Ablauf denn passt.
Weitere Debugausgaben zeigten mir gerade, dass wohl der insert selber
fehlschlaegt. Rufe ich size() nach dem letzten Insert auf, ist ein Element
weniger als erwartet in der map. Ich tendiere dazu anzunehmen, dass einfach
mein operator< falshc ist.

Wahrscheinlich sind dann einfach 2 Schlüssel äquivalent (dies ist für
a und b dann der Fall, wenn sowohl a Sind deine if/else ausbalanciert oder fehlen vielleicht ein paar {}?
Zum Testen könntest du eventuell die insert()-Funktion der Map benutzen
und das Resultat überprüfen - also statt
m[aKey] = wasSchoenes;
spaßeshalber
std::pair insert_result =
m.insert(std::make_pair(aKey, wasSchoenes));
if(insert_result.second)
{
std::cout << "Hat geklapptn";
assert(insert_result.first->first == aKey &&
insert_result.first->second == wasSchoenes); // Sollte immer stimmen!
}
else
std::cout << "Der zu " << aKey << "äquivalente Key " << insert_result.first->first
<< " war schon drin, zugehöriger Wert = " << insert_result.first->second
<< 'n';
schreiben (ich ging mal davon aus, dass die entsprechenden Ausgabeoperatoren <<
existieren).

MfG
Falk

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Stephan Menzel
Guest





PostPosted: Tue Mar 22, 2005 9:16 am    Post subject: Re: ZugrifsKlasse fuer map Reply with quote

Tobias Güntner wrote:

Quote:
Formatier's doch mal anders, vielleicht löst sich das Problem dann von
selbst.

Ja, das dachte ich mir dann auch. Und so erschien die Idee, einen kleinen
char * zu vergleichen, den jedes Objekt (dynamisch angelegt) hat. Sollte
sogar leicht performater sein.
size() zeigt mir zwar jetzt die richtige Anzahl der Elemente an, aber
interessanterweise kann ich das letzte immer noch nicht rausholen.
Ueberdies, wenn ich ueber die map iteriere und mir jeweils den Schluessel
ausgeben lasse kommt der letzte doppelt vor. Ich dachte eigentlich, dies
sei gar nicht so recht moeglich in maps.

Nun, ich nehme an, es liegt also mehr an fehlendem Verstaendnis, was den
genau beim Speichern in der map passiert als am operator<. Ich denke, ich
werde nun doch mal reindebuggen muessen. *ieks*
Vermutlich wird einfach irgendwo eine unerwartete Kopie oder dergleichen
angelegt. Es gibt fuer alles eine Erklaerung ;-)

Viele Gruesse...

Stephan
--
Freedom isn't lost in one big step when the storm-troopers
show up at your door. It is lost in little pieces, each
so small that they tend to be ignored.
Richard B. Johnson

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Stephan Menzel
Guest





PostPosted: Tue Mar 22, 2005 10:42 am    Post subject: Re: ZugrifsKlasse fuer map Reply with quote

Falk Tannhäuser wrote:

Quote:
Wahrscheinlich sind dann einfach 2 Schlüssel äquivalent (dies ist für
a und b dann der Fall, wenn sowohl a<b als auch b

Nun, dies kann definitionsgemaess in dieser Klasse nicht passieren.
Tatsaechlich ist sie u.a. zu diesem Zweck ausgelegt. Mindestens ein Element
wird sich immer unterscheiden.

Quote:
Sind deine if/else ausbalanciert oder fehlen vielleicht ein paar {}?

Hmm.
Ich mach' noch mal eine vereinfachte Kopie:

bool Key::operator<(const Key &key2) const {
if(val1 < key2.val1)
return true;
else
if(val1 == key2.val1)
if(val2 < key2.val2)
return true;
else
if (val2 == key2.val2)
if(val3 < key2.val3)
return true;
else
if(val3 == key2.val3)
return val4 < key2.val4;
return false;
}

In Wahrheit sind's ein paar mehr Werte aber ich denke das reicht. Der Code
ist wohl so ziemlich das uebelste was ich seit langem gemacht habe aber
nach meinem Verstaendnis muesste das doch funktionieren wenn mindestens ein
Wert sich unterscheidet. Ich geb' aber gerne zu dass ich recht lange dran
rumgeraetselt habe. Das sind wohl doch Sachen, die man Freitag nachmittag
nicht mehr anfangen sollte ;-)

Quote:
Zum Testen könntest du eventuell die insert()-Funktion der Map benutzen
und das Resultat überprüfen - also statt
m[aKey] = wasSchoenes;
spaßeshalber
std::pair insert_result =
m.insert(std::make_pair(aKey, wasSchoenes));
if(insert_result.second)
{
std::cout << "Hat geklapptn";
assert(insert_result.first->first == aKey &&
insert_result.first->second == wasSchoenes); // Sollte immer
stimmen!
}

Das zeigt mir nur an, dass alles OK ist.
Ich bedanke mich fuer das snippet. Nuetzlich!

Stephan
--
Freedom isn't lost in one big step when the storm-troopers
show up at your door. It is lost in little pieces, each
so small that they tend to be ignored.
Richard B. Johnson

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Rolf Magnus
Guest





PostPosted: Tue Mar 22, 2005 11:52 am    Post subject: Re: ZugrifsKlasse fuer map Reply with quote

Stephan Menzel wrote:

Quote:
Tobias Güntner wrote:

Formatier's doch mal anders, vielleicht löst sich das Problem dann von
selbst.

Ja, das dachte ich mir dann auch. Und so erschien die Idee, einen kleinen
char * zu vergleichen, den jedes Objekt (dynamisch angelegt) hat. Sollte
sogar leicht performater sein.

Du meinst den Zeigerwert selbst? Das dürfte zwar auf den meisten Plattformen
funktionieren, ist aber eigentlich nach C++-Norm nicht erlaubt.
Zeigervergleiche und generell Zeigerarithmetik sind nur innerhalb von
Arrays erlaubt.

Quote:
size() zeigt mir zwar jetzt die richtige Anzahl der Elemente an, aber
interessanterweise kann ich das letzte immer noch nicht rausholen.
Ueberdies, wenn ich ueber die map iteriere und mir jeweils den Schluessel
ausgeben lasse kommt der letzte doppelt vor. Ich dachte eigentlich, dies
sei gar nicht so recht moeglich in maps.

Es ist definitiv nicht möglich, wenn der operator< korrekt ist.

Quote:
Nun, ich nehme an, es liegt also mehr an fehlendem Verstaendnis, was den
genau beim Speichern in der map passiert als am operator<.

Üblicherweise werden die Elemente einer Map in einem binären Baum
gespeichert und dabei gleich nach Schlüssel einsortiert. Beim Suchen nach
einem Element kann durch Vergleiche des gesuchten Schlüssels mit dem
Schlüssel am aktuellen Knoten im Baum (angefangen bei der Wurzel, die im
Optimalfall quasi das "mittlere" Element enthält) jedes Mal die Anzahl an
Elementen, die den gesuchten Schlüssel haben, halbiert werden. Wenn dein
operator< nicht stimmt, kann es z.B. passieren, daß die falsche Abzeigung
genommen und damit das gesuchte Element nie gefunden wird, obwohl es in der
Map ist.

Quote:
Ich denke, ich werde nun doch mal reindebuggen muessen. *ieks*
Vermutlich wird einfach irgendwo eine unerwartete Kopie oder dergleichen
angelegt.

Was meinst du mit "unerwartete Kopie", und warum sollte die zu einem Problem
führen?

Quote:
Es gibt fuer alles eine Erklaerung Wink

Vielleicht könntest du ja auch mal ein möglichst weit reduziertes aber
komplettes Programm posten, das den Fehler zeigt. Dann wird sich mit
Sicherheit eine Erklärung finden.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Stephan Menzel
Guest





PostPosted: Tue Mar 22, 2005 1:22 pm    Post subject: Re: ZugrifsKlasse fuer map Reply with quote

Rolf Magnus wrote:

Quote:
Du meinst den Zeigerwert selbst? Das dürfte zwar auf den meisten
Plattformen funktionieren, ist aber eigentlich nach C++-Norm nicht
erlaubt. Zeigervergleiche und generell Zeigerarithmetik sind nur innerhalb
von Arrays erlaubt.

Schon klar, aber ich verletze die Norm schon durch Einsatz anderer Sachen
(file descriptors and iostreams uebergeben und so) und sowohl PLattform
(Linux) als auch Kompiler (gcc3.x) bleiben konstant so dass ich das in Kauf
nehmen kann.
Wie dem auch sei, der Zeigervergleich hat's nicht gebracht, der originale
hingegen mittlerweile schon.
Ich weiss leider noch nicht genau, wo das Problem lag aber es scheint nun zu
klappen. Vermutlich ein Programmfehler an anderer Stelle, der durch die
viele Bastelei unabsichtlich ausgebuegelt wurde. Hoffentlich.

Quote:
Üblicherweise werden die Elemente einer Map in einem binären Baum
gespeichert und dabei gleich nach Schlüssel einsortiert. Beim Suchen nach
einem Element kann durch Vergleiche des gesuchten Schlüssels mit dem
Schlüssel am aktuellen Knoten im Baum (angefangen bei der Wurzel, die im
Optimalfall quasi das "mittlere" Element enthält) jedes Mal die Anzahl an
Elementen, die den gesuchten Schlüssel haben, halbiert werden. Wenn dein
operator< nicht stimmt, kann es z.B. passieren, daß die falsche Abzeigung
genommen und damit das gesuchte Element nie gefunden wird, obwohl es in
der Map ist.

Ja, so habe ich das auch verstanden. Wodurch ja auch die logarithmische
Suchzeit erklaert wird. Leider ist es nur schlichtweg unmoeglich, in die
STL zu debuggen. Ich hab's versucht. Nie wieder!

Quote:
Ich denke, ich werde nun doch mal reindebuggen muessen. *ieks*
Vermutlich wird einfach irgendwo eine unerwartete Kopie oder dergleichen
angelegt.

Was meinst du mit "unerwartete Kopie", und warum sollte die zu einem
Problem führen?

Nun, die Key Klasse hat zum Beispiel keinen public Konstruktor ausser dem
expliziten Copyconstruktor. Normalerweise wird sie ueber Factorymethoden
instantiiert, so dass ich annahm, es gaebe vielleicht fuer die STL
moeglichkeiten, ein solches Objekt 'ausser der Reihe' zu instantiieren, bei
dem der betreffende Pointer dann null waere. Bei den Debuglaeufen fiel mir
auf, dass der Copyconstruktor beim insert in die map mindestens 4 mal
gerufen wurde. Warum frug ich mich da? Was genau passiert beim Reintun in
die map?

Quote:
Es gibt fuer alles eine Erklaerung ;-)

Vielleicht könntest du ja auch mal ein möglichst weit reduziertes aber
komplettes Programm posten, das den Fehler zeigt. Dann wird sich mit
Sicherheit eine Erklärung finden.

Sicherlich, nur leider sind mir da die Haende gebunden.
Firmenpolicy Sad Davon abgesehen waeren es ziemlich viele Klassen die ich
da posten muesste, selbst in einem vereinfachten Fall. Sorry, aber sicher
kennt Ihr das Phaenomen ;-)

Stephan
--
Freedom isn't lost in one big step when the storm-troopers
show up at your door. It is lost in little pieces, each
so small that they tend to be ignored.
Richard B. Johnson

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Mang
Guest





PostPosted: Tue Mar 22, 2005 1:28 pm    Post subject: Re: ZugrifsKlasse fuer map Reply with quote


"Stephan Menzel" <stephan-menzel (AT) web (DOT) de> schrieb im Newsbeitrag
news:3aa645F69dre8U1 (AT) individual (DOT) net...
Quote:
Tobias Güntner wrote:

Formatier's doch mal anders, vielleicht löst sich das Problem dann von
selbst.

Ja, das dachte ich mir dann auch. Und so erschien die Idee, einen kleinen
char * zu vergleichen, den jedes Objekt (dynamisch angelegt) hat. Sollte
sogar leicht performater sein.
size() zeigt mir zwar jetzt die richtige Anzahl der Elemente an, aber
interessanterweise kann ich das letzte immer noch nicht rausholen.

Du kannst es ja mal auffinden, indem Du vom end() - Iterator einmal
zurückgehst.
Gilt für dieses Element, daß operator< einmal mit dem Iterator-Element auf
der linken Seite, einmal mit dem zu suchenden key jeweils false zuückgibt,
oder einmal true (true dürfte nicht sein)?


Quote:
Ueberdies, wenn ich ueber die map iteriere und mir jeweils den Schluessel
ausgeben lasse kommt der letzte doppelt vor. Ich dachte eigentlich, dies
sei gar nicht so recht moeglich in maps.


Stimmt eigentlich.


Quote:

Nun, ich nehme an, es liegt also mehr an fehlendem Verstaendnis, was den
genau beim Speichern in der map passiert als am operator<. Ich denke, ich
werde nun doch mal reindebuggen muessen. *ieks*
Vermutlich wird einfach irgendwo eine unerwartete Kopie oder dergleichen
angelegt. Es gibt fuer alles eine Erklaerung Wink

Nur so eine Idee:
Du weißt eh, daß map immer eine Kopie vom Objekt speichert, nie das
Originalobject selber, daß Du insert übergeben hast? Also müssen diese Typen
einen ordentlichen Kopierkonstruktor / assignment-operator haben.
Kann es sein, daß sich das Ordnungsprinzip dynamisch ändert, also z.B. die
operator< - Semantik nicht immer gleich ist?

Hast Du mal verglichen, wieviele Elemente insgesamt eingefügt wurden (über
insert()), bzw. wieviele keys von denen schon vorhanden waren(über einen
Vergleich mit size())?


Thomas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Marcel Müller
Guest





PostPosted: Thu Mar 24, 2005 8:50 am    Post subject: Re: ZugrifsKlasse fuer map Reply with quote

Hallo,

Stephan Menzel schrieb:
Quote:
Nun, dies kann definitionsgemaess in dieser Klasse nicht passieren.
Tatsaechlich ist sie u.a. zu diesem Zweck ausgelegt. Mindestens ein Element
wird sich immer unterscheiden.
[...]
bool Key::operator<(const Key &key2) const {
if(val1 < key2.val1)
return true;
else
if(val1 == key2.val1)
if(val2 < key2.val2)
return true;
else
if (val2 == key2.val2)
if(val3 < key2.val3)
return true;
else
if(val3 == key2.val3)
return val4 < key2.val4;
return false;
}

In Wahrheit sind's ein paar mehr Werte aber ich denke das reicht. Der Code
ist wohl so ziemlich das uebelste was ich seit langem gemacht habe aber
nach meinem Verstaendnis muesste das doch funktionieren wenn mindestens ein
Wert sich unterscheidet.

Wenn das funktioniert, ist auch der == operator korrekt definierbar:

bool Key::operator<(const Key &key2) const {
return val1 == key2.val1 && val2 == key2.val2 ...;
}


Irgendwie habe ich aber den Eindruck, die Klasse selbst soll verhindern,
daß identische Kopieen ihresgleichen angelegt werden. Das ist aber ein
sehr eigenwilliges Design und nicht mit den STL-Containern verträglich,
da deren Elemente kopierbar sein müssen.
Üblicherweise führt erst das /Hinzufügen/ eines doppelten
Primärschlüssels zu einer Menge zu einer Ausnahme, nicht das /Erzeugen/.
Will man das Design nicht ändern, so braucht man eine Basisklasse, die
nur die Werte valX und die zugehörigen Operatoren enthält, nicht aber
die Eindeutigkeitseinschränkung.

Des weiteren ist für einen derartige Anforderung ein hash_map besser
geeignet. In diesem Fall braucht man statt des Vergleichsoperators eine
Hash-Funktion. Diese kann aus den Hashwerten der einzelnen valX per
Summe o.ä. gebildet werden. Das ist i.A. etwas zeitaufwendiger als die
Sortierte Liste, skaliert aber nahezu konstant mit der Zahl der Elemente.
--
Marcel Müller

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Stephan Menzel
Guest





PostPosted: Thu Mar 24, 2005 2:34 pm    Post subject: Re: ZugrifsKlasse fuer map Reply with quote

Marcel Müller wrote:

Quote:
Wenn das funktioniert, ist auch der == operator korrekt definierbar:

Ja, ist er auch.

Quote:
bool Key::operator<(const Key &key2) const {
return val1 == key2.val1 && val2 == key2.val2 ...;
}

Naja, eher so:
bool Key::operator==(const Key &key2) const {
return val1 == key2.val1 && val2 == key2.val2 ...;
}

;-)

Quote:
Irgendwie habe ich aber den Eindruck, die Klasse selbst soll verhindern,
daß identische Kopieen ihresgleichen angelegt werden. Das ist aber ein
sehr eigenwilliges Design und nicht mit den STL-Containern verträglich,
da deren Elemente kopierbar sein müssen.

Nein, wie kommst Du darauf?
Die Klasse hat Copyconstruktoren definiert und es duerfen durchaus
identische Kopien angelegt werden. Im uebrigen hatte der einen kleinen Bug
den ich mittlerweile fuer den urspruenglichen Fehler verantwortlich machen
konnte. An der flschaen Stelle gesucht.

Was bringt Dich zu der Vermutung?

Quote:
Des weiteren ist für einen derartige Anforderung ein hash_map besser
geeignet. In diesem Fall braucht man statt des Vergleichsoperators eine
Hash-Funktion. Diese kann aus den Hashwerten der einzelnen valX per
Summe o.ä. gebildet werden. Das ist i.A. etwas zeitaufwendiger als die
Sortierte Liste, skaliert aber nahezu konstant mit der Zahl der Elemente.

Ja, das war urspruenglich auch die Idee, aber hash maps sind derart
spaerlich dokumentiert und was ich an Doku fand sah so grauslich aus, dass
ich die Finger davon gelassen habe. So funktioniert das mittlerweile sehr
schoen.
Ab und an muss ich hin und weider ueber die komplette map iterieren, was ja
bei maps schneller gehen sollte als bei hash_maps, oder?

Stephan, gruessend
--
Freedom isn't lost in one big step when the storm-troopers
show up at your door. It is lost in little pieces, each
so small that they tend to be ignored.
Richard B. Johnson

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Marcel Müller
Guest





PostPosted: Fri Mar 25, 2005 9:11 am    Post subject: Re: ZugrifsKlasse fuer map Reply with quote

Hi,

Stephan Menzel schrieb:
Quote:
Marcel Müller wrote:

Naja, eher so:
bool Key::operator==(const Key &key2) const {
return val1 == key2.val1 && val2 == key2.val2 ...;
}

Ja, klar.


Quote:
Irgendwie habe ich aber den Eindruck, die Klasse selbst soll verhindern,
daß identische Kopieen ihresgleichen angelegt werden. Das ist aber ein
sehr eigenwilliges Design und nicht mit den STL-Containern verträglich,
da deren Elemente kopierbar sein müssen.

Nein, wie kommst Du darauf?
[...]
Was bringt Dich zu der Vermutung?

---
Quote:
Wahrscheinlich sind dann einfach 2 Schlüssel äquivalent (dies ist für
a und b dann der Fall, wenn sowohl a
Nun, dies kann definitionsgemaess in dieser Klasse nicht passieren.
Tatsaechlich ist sie u.a. zu diesem Zweck ausgelegt. Mindestens ein Element
wird sich immer unterscheiden.
---


Das hatte den Verdacht geweckt. Aber ist ja egal.


Quote:
Des weiteren ist für einen derartige Anforderung ein hash_map besser
geeignet. In diesem Fall braucht man statt des Vergleichsoperators eine
Hash-Funktion. Diese kann aus den Hashwerten der einzelnen valX per
Summe o.ä. gebildet werden. Das ist i.A. etwas zeitaufwendiger als die
Sortierte Liste, skaliert aber nahezu konstant mit der Zahl der Elemente.

Ja, das war urspruenglich auch die Idee, aber hash maps sind derart
spaerlich dokumentiert und was ich an Doku fand sah so grauslich aus, dass
ich die Finger davon gelassen habe.

http://www.sgi.com/tech/stl/hash_map.html finde ich eigentlich OK.


Quote:
Ab und an muss ich hin und weider ueber die komplette map iterieren, was ja
bei maps schneller gehen sollte als bei hash_maps, oder?

Nein, das macht keinen signifikanten Unterschied. hash_map hat nur keine
definierte Reihenfolge.

Quote:
Stephan, gruessend
--

Marcel Müller

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Andre Poenitz
Guest





PostPosted: Sat Apr 16, 2005 6:54 pm    Post subject: Re: ZugrifsKlasse fuer map Reply with quote

Tobias Güntner <fatbull (AT) users (DOT) sourceforge.net> wrote:
Quote:
Formatier's doch mal anders, vielleicht löst sich das Problem dann von
selbst.

{
if(val1 < key2.val1)
return true;
if(key2.val1 < val1)
return false;

if(val2 < key2.val2)
return true;
if(key2.val2 < val2)
return false;

Oder

if (val1 != key2.val1)
return val1 < key2.val1;

if (val2 != key2.val2)
return val2 < key2.val2;

Ist halb so lang zu schreiben und braucht i.d.R. auch weniger
Vergleiche, allerdings zusaetzlich operator!= fuer die Member.

Andre'

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Martin Krause
Guest





PostPosted: Mon Apr 18, 2005 5:20 pm    Post subject: Re: ZugrifsKlasse fuer map Reply with quote

Andre Poenitz <poenitz (AT) htwm (DOT) de> wrote:

Quote:
Tobias Güntner <fatbull (AT) users (DOT) sourceforge.net> wrote:
Formatier's doch mal anders, vielleicht löst sich das Problem dann von
selbst.

{
if(val1 < key2.val1)
return true;
if(key2.val1 < val1)
return false;

if(val2 < key2.val2)
return true;
if(key2.val2 < val2)
return false;

Oder

if (val1 != key2.val1)
return val1 < key2.val1;

if (val2 != key2.val2)
return val2 < key2.val2;

Ist halb so lang zu schreiben und braucht i.d.R. auch weniger
Vergleiche, allerdings zusaetzlich operator!= fuer die Member.

Oder als Einzeiler mit operator=:

return (val1 = key2.val1) ? (val2
--
------------------- Martin Krause ----------------------------
email: [email]mkr-dr350 (AT) telda (DOT) net[/email] | DRZ 400S


--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.