Seite 1 von 1

Wrapper für std::map

Verfasst: 20.08.2011, 20:30
von odenter
Ich brauch mal fachkundige Hilfe.

Ich will std::map wrappen um später events zu feuern wenn z.B. Items eigenfügt oder geändert werden. Für std::vector und std::list habe ich das erfolgreich hinbekommen. Bei std::map macht der [] operator Probleme.

Hier der Code

Code: Alles auswählen

#pragma once

#include <map>

template <typename KEY, typename VALUE>
class MapBase
{
private:
  std::map<KEY, VALUE> *_items;

public:
  typedef typename std::map<KEY, VALUE>::iterator Iterator;
  typedef typename std::map<KEY, VALUE>::reverse_iterator ReverseIterator;

  MapBase()
  {
    _items = new std::map<KEY, VALUE>;
  }

  ~MapBase()
  {
    this->Clear();
  }

  void Clear()
  {
    _items->clear();
  }

  void Insert(const KEY& key, const VALUE& value)
  {
    _items->insert(std::pair<KEY, VALUE>(key, value));
  }

  Iterator Begin()
  {
    return _items->begin();
  }

  Iterator End()
  {
    return _items->end();
  }

  VALUE& operator[] (KEY& key)
  {
    return (*_items)[key];
  }
};
Achso Fehlermeldung ist folgende:

Code: Alles auswählen

main.cpp
1>c:\_daten\temp\mwisim\main.cpp(40): error C2679: Binärer Operator '[': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ 'int' akzeptiert (oder keine geeignete Konvertierung möglich)
1>          c:\_daten\temp\mwisim\core\mapbase.h(45): kann 'double &MapBase<KEY,VALUE>::operator [](KEY &)' sein
1>          with
1>          [
1>              KEY=int,
1>              VALUE=double
1>          ]
1>          bei Anpassung der Argumentliste '(MapBase<KEY,VALUE>, int)'
1>          with
1>          [
1>              KEY=int,
1>              VALUE=double
1>          ]
1>c:\_daten\temp\mwisim\main.cpp(41): error C2679: Binärer Operator '[': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ 'int' akzeptiert (oder keine geeignete Konvertierung möglich)
1>          c:\_daten\temp\mwisim\core\mapbase.h(45): kann 'double &MapBase<KEY,VALUE>::operator [](KEY &)' sein
1>          with
1>          [
1>              KEY=int,
1>              VALUE=double
1>          ]
1>          bei Anpassung der Argumentliste '(MapBase<KEY,VALUE>, int)'
1>          with
1>          [
1>              KEY=int,
1>              VALUE=double
1>          ]
Testcode sieht so aus

Code: Alles auswählen

  MapBase<int, double> m;

  m.Insert(1, 2.345);
  m.Insert(2, 5.43);
  m.Insert(3, 1.2456);

  double dd = m[2]; 
  // oder halt
  m[2] = 3.333;

Hat jemand nen Tip für mich?

Re: Wrapper für std::map

Verfasst: 20.08.2011, 22:56
von EyDu
Hallo.

Du hast einfach nur ein `const` vergessen:

Code: Alles auswählen

VALUE& operator[] (const KEY& key)
{
return (*_items)[key];
}
Etwas Kritik an deinem Code habe ich aber noch: Warum benutzt du für `_items` einen Pointer? Der ist hier eigentlich eine unnötige Indirektion. Aufbauend darauf hast du dir im Destruktor auch gleich ein hübsches Speicherleck gebaut ;-) Du gibst zwar den Inhalt der Map frei, die Map selbst aber nicht.

Sebastian

Re: Wrapper für std::map

Verfasst: 20.08.2011, 23:09
von odenter
EyDu hat geschrieben:Hallo.

Du hast einfach nur ein `const` vergessen:

Code: Alles auswählen

VALUE& operator[] (const KEY& key)
{
return (*_items)[key];
}
Danke!
EyDu hat geschrieben: Etwas Kritik an deinem Code habe ich aber noch: Warum benutzt du für `_items` einen Pointer? Der ist hier eigentlich eine unnötige Indirektion. Aufbauend darauf hast du dir im Destruktor auch gleich ein hübsches Speicherleck gebaut ;-) Du gibst zwar den Inhalt der Map frei, die Map selbst aber nicht.
Sebastian
Gnarf

Danke. Bei der Liste und dem Vector hatte ich das "delete", hab vld noch nicht eingebunden, der hätte mir das dann gesagt, gleich mal ändern.
Es gibt keinen bestimmten Grund warum ich das so gemacht habe, vermutlich war ich in Gedanken schon weiter. :)

Re: Wrapper für std::map

Verfasst: 21.08.2011, 15:02
von BeRsErKeR
new und delete sind hier wirklich überflüssig und bringen wie schon erwähnt nur Nachteile. Das Clear im Destruktor ist meiner Meinung nach auch überflüssig; die std::map wird sowieso zerstört.

Re: Wrapper für std::map

Verfasst: 21.08.2011, 15:25
von Krishty
Richtig.

Außerdem weißt du schon, dass operator [] ein neues Element anlegt, falls der Schlüssel ins Leere führt? Wenn du ihn benutzt hast du also keine Möglichkeit, festzustellen, wann etwas eingefügt wurde (es sei denn, du fängst mit Umwegen an wie, vorher und nachher die Größe abzufragen und beide Werte zu vergleichen). Denk nochmal darüber nach, ob find() in einem nach außen hin const gewrappten operator [] nicht die bessere Wahl wäre.

(Persönlich verabscheue ich die Entscheidung, dass da völlig kontraintuitiv ein Mutator im Inspektorspelz implementiert wurde.)

Re: Wrapper für std::map

Verfasst: 21.08.2011, 15:39
von odenter
Krishty hat geschrieben:Richtig.

Außerdem weißt du schon, dass operator [] ein neues Element anlegt, falls der Schlüssel ins Leere führt? Wenn du ihn benutzt hast du also keine Möglichkeit, festzustellen, wann etwas eingefügt wurde (es sei denn, du fängst mit Umwegen an wie, vorher und nachher die Größe abzufragen und beide Werte zu vergleichen). Denk nochmal darüber nach, ob find() in einem nach außen hin const gewrappten operator [] nicht die bessere Wahl wäre.

(Persönlich verabscheue ich die Entscheidung, dass da völlig kontraintuitiv ein Mutator im Inspektorspelz implementiert wurde.)
Das Verhalten ist so gewünscht.

Re: Wrapper für std::map

Verfasst: 22.08.2011, 00:13
von BeRsErKeR
odenter hat geschrieben:
Krishty hat geschrieben:Richtig.

Außerdem weißt du schon, dass operator [] ein neues Element anlegt, falls der Schlüssel ins Leere führt? Wenn du ihn benutzt hast du also keine Möglichkeit, festzustellen, wann etwas eingefügt wurde (es sei denn, du fängst mit Umwegen an wie, vorher und nachher die Größe abzufragen und beide Werte zu vergleichen). Denk nochmal darüber nach, ob find() in einem nach außen hin const gewrappten operator [] nicht die bessere Wahl wäre.

(Persönlich verabscheue ich die Entscheidung, dass da völlig kontraintuitiv ein Mutator im Inspektorspelz implementiert wurde.)
Das Verhalten ist so gewünscht.

Dann feuerst du also nur Events, wenn Elemente per Insert eingefügt werden und nicht wenn sie per []-operator eingefügt werden? Der []-operator von std::map ruft ja intern auch ein std::map::insert auf. Für mich ist das sehr unintuitiv und inkonsequent. Aber du wirst schon wissen was du da tust. ;)

Re: Wrapper für std::map

Verfasst: 22.08.2011, 19:58
von odenter
BeRsErKeR hat geschrieben:
odenter hat geschrieben:
Krishty hat geschrieben:Richtig.

Außerdem weißt du schon, dass operator [] ein neues Element anlegt, falls der Schlüssel ins Leere führt? Wenn du ihn benutzt hast du also keine Möglichkeit, festzustellen, wann etwas eingefügt wurde (es sei denn, du fängst mit Umwegen an wie, vorher und nachher die Größe abzufragen und beide Werte zu vergleichen). Denk nochmal darüber nach, ob find() in einem nach außen hin const gewrappten operator [] nicht die bessere Wahl wäre.

(Persönlich verabscheue ich die Entscheidung, dass da völlig kontraintuitiv ein Mutator im Inspektorspelz implementiert wurde.)
Das Verhalten ist so gewünscht.

Dann feuerst du also nur Events, wenn Elemente per Insert eingefügt werden und nicht wenn sie per []-operator eingefügt werden? Der []-operator von std::map ruft ja intern auch ein std::map::insert auf. Für mich ist das sehr unintuitiv und inkonsequent. Aber du wirst schon wissen was du da tust. ;)
Ja genau nur wenn insert von mir aufgerufen wird. Da auf absehbare Zeit niemand anderes an dem Code rumfummelt und ich den Operator nur zum abrufen verwenden will, für Werte die vorher defenitiv einefügt wurden, kann da nicht viel schief gehen. :)

Re: Wrapper für std::map

Verfasst: 22.08.2011, 20:06
von Krishty
Sobald das Ding kurz vor der Freigabe steht, schick mir bitte eine PM mit dem Namen, damit ich es bloß nie versehentlich benutze. Echt – du könntest mit der Operatorüberladung und const *perfekt* verhindern, dass jemals irgendwer Murks mit der Klasse baut. Und fährst stattdessen die trust me on this one-Schiene. Wegen sowas ist Software heute immernoch so scheiße wie sie es schon immer war.

Re: Wrapper für std::map

Verfasst: 22.08.2011, 20:47
von odenter
Krishty hat geschrieben:Sobald das Ding kurz vor der Freigabe steht, schick mir bitte eine PM mit dem Namen, damit ich es bloß nie versehentlich benutze. Echt – du könntest mit der Operatorüberladung und const *perfekt* verhindern, dass jemals irgendwer Murks mit der Klasse baut. Und fährst stattdessen die trust me on this one-Schiene. Wegen sowas ist Software heute immernoch so scheiße wie sie es schon immer war.
Dann ist das eben scheiss Software die von mir für mich geschrieben wurde. ^^

Re: Wrapper für std::map

Verfasst: 22.08.2011, 20:55
von TGGC
Ich verstehs nicht. Wo ist der Sinn dieses Wrappers? Du solltest dir nur zur Sicherheit noch einen Wrapper fuer deinen Wrapper schreiben...

Re: Wrapper für std::map

Verfasst: 22.08.2011, 21:33
von waigie
Den Sinn des Wrappers versteh ich aber auch nicht so ganz. Eigentlich sollte sich das ganze einfacher Lösen lassen wenn du von std::map ableitest und daraufhin nur die insert und delete Methode abänderst, das du dein Event feuerst und dann den parent Code ausführst.
So umgehst du die Probleme die dein Code jetzt erzeugt.

Re: Wrapper für std::map

Verfasst: 22.08.2011, 21:43
von Krishty
Prinzipiell hast du damit recht; persönlich bin ich aber kontra Vererbung und pro Komposition (bin eher ein explizites Stück Mensch und finde, dass man bei Vererbung weniger schreiben, aber mehr leiden muss und dass es bei Komposition umgekehrt ist). Da möchte ich meinen Mund mangels Erfahrung aber garnicht zu weit aufreißen.

Ich merke gerade, dass ich nicht einmal Wissen um den richtigen Terminus habe: Delegation, Komposition, Forwarding, blabla. Ignoriert mich bitte.

Re: Wrapper für std::map

Verfasst: 22.08.2011, 23:30
von BeRsErKeR
waigie hat geschrieben:Eigentlich sollte sich das ganze einfacher Lösen lassen wenn du von std::map ableitest und daraufhin nur die insert und delete Methode abänderst, das du dein Event feuerst und dann den parent Code ausführst.
STL Container (oder allgemein Klassen aus der STL) sind nicht gerade dafür berühmt, dass man von ihnen gut erben kann. Das Wörtchen virtual sucht man hier nämlich vergeblich. Daher ist ein Wrapper mitunter schon der Vererbung vorzuziehen. Ganz einfach weil es nicht anders geht. Siehe Glib::ustring. Der erbt auch nicht von std::string, sondern implementiert alles neu bzw. wrappt es halt.

Re: Wrapper für std::map

Verfasst: 23.08.2011, 09:19
von odenter
TGGC hat geschrieben:Ich verstehs nicht. Wo ist der Sinn dieses Wrappers? Du solltest dir nur zur Sicherheit noch einen Wrapper fuer deinen Wrapper schreiben...
Dann hast Du wohl nicht richtig gelesen und verstanden was ich machen will.

Re: Wrapper für std::map

Verfasst: 23.08.2011, 09:49
von TGGC
Wie gesagt, ich verstehe es nicht. Es erscheint mir voellig sinnlos. Du willst sowas machen wir "map[blubb]=bla;DoEvent();" Warum schreibst du dann nicht eine Funktion die das macht? Warum musst du std::map wrappen? std::map ist ja bereits ein Wrapper.

Re: Wrapper für std::map

Verfasst: 23.08.2011, 10:02
von odenter
TGGC hat geschrieben:Wie gesagt, ich verstehe es nicht. Es erscheint mir voellig sinnlos. Du willst sowas machen wir "map[blubb]=bla;DoEvent();" Warum schreibst du dann nicht eine Funktion die das macht? Warum musst du std::map wrappen? std::map ist ja bereits ein Wrapper.
Nein ich will sowas machen wie:

Ist jetzt bischen pseudo code und egal ob Vector, List oder Map

Code: Alles auswählen

template <typename KEY, typename VALUE>
class MapBase<KEY, VALUE>
{
public:
  boost::signal<void (KEY, VALUE)> ItemInserting;
  boost::signal<void (KEY, VALUE)> ItemInserted;
  boost::signal<void (KEY, VALUE)> ItemAccessing;
  boost::signal<void (KEY, VALUE)> ItemAccessed;
};
MapBase<int, string> m;
m.ItemInserting.connect(&itemInserting_eventHandler);
m.ItemInserted.connect(&itemInserted_eventHandler);
m.ItemAccessing.connect(&itemAccessing_eventHandler);
m.ItemAccessed.connect(&itemAccessed_eventHandler);

m.Insert(1, "karl");
m.Insert(2, "dall");
etc.

// und dann vielleicht irgendwann mal um Daten direkt abzufragen
string name = m[2];
// oder halt einen vorhandenen Wert abändern.
m[2] = "meyer";
Dann noch ne Basis für VALUE um auch dort ein Changeing und Changed Event einbauen zu können und ich habe alles was ich will. :)
Die Changeing Events müssen natürlich abbrechbar sein, so ein bischen was muss ich da schon noch machen.

Re: Wrapper für std::map

Verfasst: 23.08.2011, 11:49
von BeRsErKeR
Ich kann da TGGC nur zustimmen. Eine Funktion tut es in dem Fall auch. Man muss nicht immer alles kapseln und wrappen.

Re: Wrapper für std::map

Verfasst: 23.08.2011, 13:09
von odenter
BeRsErKeR hat geschrieben:Ich kann da TGGC nur zustimmen. Eine Funktion tut es in dem Fall auch. Man muss nicht immer alles kapseln und wrappen.
Man kann soviele machen, man kann aber auch sovieles lassen. Man kann auch eine Engine in C schreiben, muss nicht immer C++ sein, meistens tut es sogar eine fertige. ;)

Nichts gegen Dich, aber mir wird es hier langsam zu blöde, besonders die neunmal klugen Kommentare von Leuten die keine Ahnung haben was ich mache, machen will oder warum ich etwas genauso mache wie ich es mache. ;) Das ist gerade in diesem Forum sehr stark ausgeprägt.
Euer ist immer zweimal solange wie meiner und jetzt habsch meine Ruhe.

Noch einen schönen tag wünsche ich.

Re: Wrapper für std::map

Verfasst: 23.08.2011, 13:29
von Chromanoid
Lass dich von diesem "Mockup" nicht ins Bockshorn jagen :).

Re: Wrapper für std::map

Verfasst: 23.08.2011, 16:39
von TGGC
Warum faengst du an mich persoenlich zu beleidigen, nur weil ich nicht verstehe, was du machen willst?

Re: Wrapper für std::map

Verfasst: 23.08.2011, 17:03
von CodingCat
odenter hat geschrieben:Man kann soviele machen, man kann aber auch sovieles lassen. Man kann auch eine Engine in C schreiben, muss nicht immer C++ sein, meistens tut es sogar eine fertige. ;)
odenter hat geschrieben:Mir wird es hier langsam zu blöde, besonders die neunmal klugen Kommentare von Leuten die keine Ahnung haben was ich mache, machen will oder warum ich etwas genauso mache wie ich es mache.
Ein Wrapper ist dann sinnvoll, wenn du damit unkorrekte Nutzung wesentlich besser ausschließen kannst als ohne. Wenn dein Wrapper schon Löcher hat, dann tut es eine simple Funktion wesentlich besser, weil von vorneherein klar ist, dass NUR bei Benutzung der Funktion korrektes Verhalten gewährleistet ist.
In deinem Fall TUT der Wrapper nur SO, als würde er (in seiner Funktion als Wrapper) korrektes Verhalten GARANTIEREN, du weigerst dich aber, gut gemeinte Vorschläge zur Absicherung des Wrappers ernstzunehmen (z.B. einfach eine vernünfige Implementierung von operator [], siehe Krishty), mit der Begründung, der Wrapper würde eh nur auf bestimmte Weise genutzt. Damit machst du deinen Wrapper nicht nur selbst absolut überflüssig, sondern auch noch gefährlich, und irgendwann WIRD er auch deine Software zerreißen.

Re: Wrapper für std::map

Verfasst: 23.08.2011, 20:48
von odenter
CodingCat hat geschrieben:
odenter hat geschrieben:Man kann soviele machen, man kann aber auch sovieles lassen. Man kann auch eine Engine in C schreiben, muss nicht immer C++ sein, meistens tut es sogar eine fertige. ;)
odenter hat geschrieben:Mir wird es hier langsam zu blöde, besonders die neunmal klugen Kommentare von Leuten die keine Ahnung haben was ich mache, machen will oder warum ich etwas genauso mache wie ich es mache.
Ein Wrapper ist dann sinnvoll, wenn du damit unkorrekte Nutzung wesentlich besser ausschließen kannst als ohne. Wenn dein Wrapper schon Löcher hat, dann tut es eine simple Funktion wesentlich besser, weil von vorneherein klar ist, dass NUR bei Benutzung der Funktion korrektes Verhalten gewährleistet ist.
In deinem Fall TUT der Wrapper nur SO, als würde er (in seiner Funktion als Wrapper) korrektes Verhalten GARANTIEREN, du weigerst dich aber, gut gemeinte Vorschläge zur Absicherung des Wrappers ernstzunehmen (z.B. einfach eine vernünfige Implementierung von operator [], siehe Krishty), mit der Begründung, der Wrapper würde eh nur auf bestimmte Weise genutzt. Damit machst du deinen Wrapper nicht nur selbst absolut überflüssig, sondern auch noch gefährlich, und irgendwann WIRD er auch deine Software zerreißen.
Ein Wrapper ist immer dann Sinnvoll wenn ich Funktionalität erweitern/ändern will oder Verhalten verändern will.
Du weisst doch gar nicht in welchem Fall ich welches Verhalten garantieren will bzw. benötige.

Was ist wenn ich Dir sage das das ich folgende unterschiedliche Verhalten benötige:
a.) Exception sofern Key nicht vorhanden ist (bool an Constructor, Vorschlag zur Lösung steht hier im Thread)
b.) Wenn Key/Item nicht da ist anlegen (Gegenteil von a.)
c.) Events die bei Aufruf verschiedener Methoden geworfen werden (die werden immer geworfen muss ja niemand abbonieren)
d.) Änderung der Benamung der Methoden (public Methoden schreibe ich groß nicht klein)

Es hängt immer davon ab wie man in den Wald hinruft, es gab vernünftig formulierte Kritik und Hinweise auf echte Fehler.
Auch Du unterstellst das das anlegen von KEY/VALUE Paaren unkorrektes Verhalten ist, was schlicht nicht zutrifft. Weiter oben hatte ich bereits geschrieben das dieses Verhalten, neben den anderen hier jetzt aufgezählen, explizit erwünscht ist.
Da die erbende Klasse, Constructor ist im Beispiel nicht protected ich weiss ist ja auch nur ein Beispiel für eine Frage gewesen, auch weiss welches Verhalten Sie erwartet sehe ich kein Problem, zumal wie geschrieben ich das Ding benutze und ich weiss wofür ich mir das gebaut habe.
Die Alternative wäre eine Klasse für jedes Verhalten, kann man machen, für std::map wären das vier, für std::vector ebenfalls und für std::list zwei. Macht zehen Klassen gegen drei. Da das ganze ne Hobbynummer ist gehe ich den Kompromiss drei zu 10 Klassen gerne ein.

Statt zu fragen was ich will, wird aufgrund von eigenen Erfahrungen angenommen welches Verhalten ich haben will und dann mit Kommentaren gepaart wie ich etwas doch viel besser machen sollte. ;)
Zumal ich mich frage wie ich, um bei dem ursprünglich geposteten Beispiel zu bleiben, beim einfügen eines Items (egal ob list, vector oder map) ein Event werfen soll ohne einen Wrapper zu schreiben in dem eine Methode ist der das Event wirft und danach oder davor das Item einfügt bzw. das einfügen verhindert abhängig von den Eventparametern?

Re: Wrapper für std::map

Verfasst: 23.08.2011, 21:03
von TGGC
odenter hat geschrieben:a.) Exception sofern Key nicht vorhanden ist (bool an Constructor, Vorschlag zur Lösung steht hier im Thread)
b.) Wenn Key/Item nicht da ist anlegen (Gegenteil von a.)
c.) Events die bei Aufruf verschiedener Methoden geworfen werden (die werden immer geworfen muss ja niemand abbonieren)
d.) Änderung der Benamung der Methoden (public Methoden schreibe ich groß nicht klein)
a) kann man als eine Template-Funktion mit 3 Zeilen implementieren
b) macht std::map automatisch bei []-Zugriffen
c) warum musst du einen Event werfen, wenn eine Funktion aufgerufen wird? Du rufst die Funktion ja selbst auf und solltest im Bilde sein
d) naja, wers braucht...

Re: Wrapper für std::map

Verfasst: 23.08.2011, 21:23
von CodingCat
odenter hat geschrieben:Auch Du unterstellst das das anlegen von KEY/VALUE Paaren unkorrektes Verhalten ist, was schlicht nicht zutrifft. Weiter oben hatte ich bereits geschrieben das dieses Verhalten, neben den anderen hier jetzt aufgezählen, explizit erwünscht ist.
Falsch, ich rede von dem unkorrekten Verhalten des Einfügens neuer Elemente OHNE Notification:
odenter hat geschrieben:Ja genau nur wenn insert von mir aufgerufen wird. Da auf absehbare Zeit niemand anderes an dem Code rumfummelt und ich den Operator nur zum abrufen verwenden will, für Werte die vorher defenitiv einefügt wurden, kann da nicht viel schief gehen.
Du sprichst selbst von "schief gehen", wenn der Schlüssel vorher nicht vorhanden gewesen ist, insofern unterstelle ich dir gar nichts, du hast das unkorrekte Verhalten bereits selbst als solches erkannt und beschrieben.

Was wir jetzt schon mit zig Posts versuchen, dir vor Augen zu führen, ist, dass dein Container sich schlicht absolut inkonsequent verhält, wenn er sowohl das Einfügen mit als auch ohne Notification erlaubt, ohne dafür aussagekräftige Methodennamen zu wählen. Letztlich muss es immer das Ziel sein, möglichst wenig Überraschung bei der Nutzung einer neuen Klassen hervorzurufen, und das Konzept der std::map enthält ganz klar mehr oder weniger austauschbar die insert-Methode sowie den operator [] zum Einfügen von Elementen anzubieten. Dass die beiden sich einfach so völlig in ihrer Verhaltensweise unterscheiden, ergibt deshalb überhaupt keinen Sinn. Sollte derartiges Verhalten wirklich notwendig sein, dann wäre das Mindeste, einen aussagekräftigen Methodennamen wie insertWithoutNotification zu wählen.
odenter hat geschrieben:Ein Wrapper ist immer dann Sinnvoll wenn ich Funktionalität erweitern/ändern will oder Verhalten verändern will.
Dafür sind Wrapper doch im Allgemeinen viel zu umständlich, weil du einfach jede blöde unveränderte Methode nochmal weiterleiten musst. Wrapper lohnen sich dann, wenn du konsistentes Verhalten erzwingen willst, welches sich alleine durch das Angebot eines losen Funktionenverbundes nicht garantieren lässt. Ein anderer Fall ist das Ändern von Verhalten bei GLEICHEM Interface, da du aber das Interface mit deinem Wrapper auch völlig umkrempelst, trifft das hier genauso wenig zu. Tatsächlich verlangst du in deinen bisherigen Beschreibungen dieses Threads gar kein konsistentes Verhalten, sondern du erlaubst Veränderung sowohl mit als auch ohne Notification, womit die Notwendigkeit einer Erzwingung wegfällt, und eine simple Funktion insertAndNotify den Job genauso gut täte, siehe TGGC/Template-Funktion.

Wenn du unbedingt einen Wrapper willst, und sei es alleine wegen des Syntax Sugars, dann versuch doch bitte, diesen wenigstens konsequent umzusetzen. Es kostet dich überhaupt gar nichts, den operator [] entsprechend anzupassen, dass auch er Notifications sendet, und es ist mir wirklich unverständlich, warum du dich so dagegen verwehrst, offensichtlich unsinnigen Code in sinnvollen zu verwandeln.
odenter hat geschrieben:Statt zu fragen was ich will, wird aufgrund von eigenen Erfahrungen angenommen welches Verhalten ich haben will und dann mit Kommentaren gepaart wie ich etwas doch viel besser machen sollte. ;)
Darum stecken wir Energie in dieses Forum, um anderen Vorschläge zu machen und Erfahrung weiterzugeben. Darin liegt der eigentliche Wert des Austauschs mit anderen, irgendwelche albernen Compilerfehler kann dir auch jede x-beliebige Doku beantworten.

Re: Wrapper für std::map

Verfasst: 24.08.2011, 00:00
von hagbard
Wo steht eigentlich geschrieben dass ein Wrapper alle Methoden der gewrappten Klasse auch nach aussen anbieten muss? Meiner Meinung nach sollte ein Wrapper eher die angebotenen Methoden auf das notwendige Minimum reduzieren um solch Inkosistenzen zu vermeiden (Get, Add, Change und Delete alles andere ist syntaktischer Zucker). Nur so ein Vorschlag aber ich bin momentan auch gerade nicht so im Training was C++ betrifft...

Re: Wrapper für std::map

Verfasst: 24.08.2011, 00:20
von CodingCat
Hat das irgendwer behauptet? Du musst natürlich nicht jede Methode anbieten, im Gegenteil, dein Ziel ist es ja gerade, konsistentes Verhalten durch gezieltes Verbieten oder Kontrollieren bestimmter Zugriffsarten zu erzwingen. Dennoch hast du beim Wrapping sehr schnell einen ganz beachtlichen Grundstock an unverändert weitergegebener Funktionalität.
Gerade bei Containers möchtest du in der Regel mindestens noch Möglichkeiten der Iteration, Abfrage der Größe, und im Falle von assoziativen Containers noch verschiedene Arten der Suche nach Elementen (automatisches Einfügen, nur Suchen, Existenzcheck) anbieten. Ein weiterer Nachteil von third-party Wrappers liegt genau darin, dass leicht simple Funktionalität vergessen wird, der Wrapper aber nun keinerlei Zugriff mehr auf dieselbe bietet.

Re: Wrapper für std::map

Verfasst: 24.08.2011, 01:28
von odenter
Offensichtlich verstehen wir unter "Wrapper" unterschiedliches. Belassen wir es dabei.

Also der Code wurde Verbessert und zwar durch die Hinweise im 2., 4. und 5. Post.

const VALUE& operator[](const KEY& key) fällt aus genannten Gründen aus, da es explizit erwünscht ist das in dem Fall ein Item erzeugt wird.
Ich hatte meinen Code geändert nachdem BeRsErKeR mich auf das Verhalten hingewiesen hatte.

Dann kam das Totschlagargument auf das ich auf die gleiche Weise reagiert habe, hier begann die Diskussion zu enden.

Dann kam der, in meinen Augen, völlig überflüssige Kommentar einen Wrapper für einen Wrapper zu schreiben den ich als Flame werte.

Spätestens hier war die Diskussion am Ende.

Dann wurde mir vorgeschlagen eine Funktion zu bauen die im ursprünglich geposteten Beispielcode auf Seite eins bereits existiert, die schimpft sich Insert(...). Ich hatte erklärt das ich Events werfen will, ich habe vorausgesetzt das klar ist das ich das in der Methode mache.
Machen tut man das ja weil man andere Objekte über eine Veränderung informieren möchte.

Dann kam die Mietzekatze :) dazu und versucht mir zu erklären das mein Wrapper unsinnig ist und erzählt mir das meine Antwort, auf das Totschlagargument von Krishty, mein Argument wäre meinen Code nicht zu verbessern.
Und verweist auf den Vorschlag der Template Funktion die ich bereits habe.

Ich weiss nicht was Ihr wollt. :)

Re: Wrapper für std::map

Verfasst: 24.08.2011, 08:58
von TGGC
Oder die Geschichte in kurz: wir haben recht und ich _bin_ es.

Re: Wrapper für std::map

Verfasst: 24.08.2011, 19:30
von hagbard
@CodingCat:

Das war eher ein Denkanstoss in Richtung von odenter den Zugriff auf die überladenen Operatoren nicht nach aussen zu wrappen. Zugegeben etwas spartanische Lösung aber lieber ein paar Zeichen mehr eintippen bei jeden Aufruf als mich mit so hässlichen Nebeneffekten.