Wrapper für std::map

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
odenter
Establishment
Beiträge: 207
Registriert: 26.02.2009, 11:58

Wrapper für std::map

Beitrag 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?
EyDu
Establishment
Beiträge: 101
Registriert: 24.08.2002, 18:52
Wohnort: Berlin
Kontaktdaten:

Re: Wrapper für std::map

Beitrag 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
odenter
Establishment
Beiträge: 207
Registriert: 26.02.2009, 11:58

Re: Wrapper für std::map

Beitrag 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. :)
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Wrapper für std::map

Beitrag 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.
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Wrapper für std::map

Beitrag 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.)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
odenter
Establishment
Beiträge: 207
Registriert: 26.02.2009, 11:58

Re: Wrapper für std::map

Beitrag 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.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Wrapper für std::map

Beitrag 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. ;)
Ohne Input kein Output.
odenter
Establishment
Beiträge: 207
Registriert: 26.02.2009, 11:58

Re: Wrapper für std::map

Beitrag 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. :)
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Wrapper für std::map

Beitrag 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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
odenter
Establishment
Beiträge: 207
Registriert: 26.02.2009, 11:58

Re: Wrapper für std::map

Beitrag 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. ^^
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Wrapper für std::map

Beitrag von TGGC »

Ich verstehs nicht. Wo ist der Sinn dieses Wrappers? Du solltest dir nur zur Sicherheit noch einen Wrapper fuer deinen Wrapper schreiben...
waigie
Beiträge: 82
Registriert: 20.05.2009, 19:37

Re: Wrapper für std::map

Beitrag 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.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Wrapper für std::map

Beitrag 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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Wrapper für std::map

Beitrag 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.
Ohne Input kein Output.
odenter
Establishment
Beiträge: 207
Registriert: 26.02.2009, 11:58

Re: Wrapper für std::map

Beitrag 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.
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Wrapper für std::map

Beitrag 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.
odenter
Establishment
Beiträge: 207
Registriert: 26.02.2009, 11:58

Re: Wrapper für std::map

Beitrag 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.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Wrapper für std::map

Beitrag von BeRsErKeR »

Ich kann da TGGC nur zustimmen. Eine Funktion tut es in dem Fall auch. Man muss nicht immer alles kapseln und wrappen.
Ohne Input kein Output.
odenter
Establishment
Beiträge: 207
Registriert: 26.02.2009, 11:58

Re: Wrapper für std::map

Beitrag 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.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4262
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Wrapper für std::map

Beitrag von Chromanoid »

Lass dich von diesem "Mockup" nicht ins Bockshorn jagen :).
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Wrapper für std::map

Beitrag von TGGC »

Warum faengst du an mich persoenlich zu beleidigen, nur weil ich nicht verstehe, was du machen willst?
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Wrapper für std::map

Beitrag 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.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
odenter
Establishment
Beiträge: 207
Registriert: 26.02.2009, 11:58

Re: Wrapper für std::map

Beitrag 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?
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Wrapper für std::map

Beitrag 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...
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Wrapper für std::map

Beitrag 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.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
hagbard
Beiträge: 66
Registriert: 05.08.2010, 23:54

Re: Wrapper für std::map

Beitrag 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...
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Wrapper für std::map

Beitrag 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.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
odenter
Establishment
Beiträge: 207
Registriert: 26.02.2009, 11:58

Re: Wrapper für std::map

Beitrag 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. :)
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Wrapper für std::map

Beitrag von TGGC »

Oder die Geschichte in kurz: wir haben recht und ich _bin_ es.
hagbard
Beiträge: 66
Registriert: 05.08.2010, 23:54

Re: Wrapper für std::map

Beitrag 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.
Antworten