Vortwärts Deklarationen für verschachtelte maps mit typedefs



  • Ich benötige ineinander verschachtelte maps. Im Prinzip wird dadurch ein Baum aufgebaut.

    Ich habe Felder (identifiziert durch TFIELD). Über eine Map TMAP_FILTER_FIELDS greife ich nun zu und erhalte eine weitere Map von Werten TMAP_FILTER_VALUES.
    Jeder der TMAP_FILTER_VALUES hat nun wieder einen Key (TVALUE) und der Zugriff erfolgt wieder auf eine Feldliste TMAP_FILTER_FIELDS.

    Da die Klassen inenander verschachtelt sind muss ich eine Vorwärtsdeklaration benutzten. Alerdings gibt es keine typedef Vorwärtsdeklaration:

    Folgernder Code geht nicht:

    // Vorwärtsdeklaration für einen typedef???
    typedef TMAP_FILTER_FIELDS;  // das gibt es nicht
    struct TMAP_FILTER_FIELDS;   // typedef ist keine struct
    class TMAP_FILTER_FIELDS;    // typedef ist keine class
    typedef std::map<TFIELD,TMAP_FILTER_FIELDS> TMAP_FILTER_VALUES;
    typedef std::map<TVALUE,TMAP_FILTER_VALUES> TMAP_FILTER_FIELDS;
    ...
    TMAP_FILTER_FIELDS	m_mapFilter;
    

    Gelöst habe ich es aktuell mit einer struct, die nur wiederum nur den Folgetyp enthält. Was ich allerdings als unnötig empfinde. Denn ich muss beim Zugriff dann auch den Member ansprechen und ich habe sowieso nur einen. Warum kann dieser also nicht gleich der zweite Map Typ werden.

    struct S_HIST_FILTER_VALUE_DEF;
    typedef std::map<TFIELD,S_HIST_FILTER_VALUE_DEF> TMAP_FILTER_VALUES;
    typedef std::map<TVALUE,TMAP_FILTER_VALUES> TMAP_FILTER_FIELDS;
    struct S_HIST_FILTER_VALUE_DEF
    {
     TMAP_FILTER_FIELDS	m_mapFields;
    };
    ...
    TMAP_FILTER_FIELDS	m_mapFilter;
    

    Gibt es eine andere Lösung als mit dieser Hilfsstruktur.



  • Das geht nicht direkt, da du so eine Endlosrekursion hättest.

    std::map<TFIELD, TMAP_FILTER_FIELDS>
    std::map<TFIELD, std::map<TVALUE, TMAP_FILTER_VALUES> >
    std::map<TFIELD, std::map<TVALUE, std::map<TFIELD, TMAP_FILTER_FIELDS> > >
    ...
    

    Mit der Vorwärtsdeklaration hast du hinegen eine Indirektion. Wobei ich mir nicht sicher bin, ob sich jede StdLib-Implementierung damit klarkommt, schliesslich dürfte eine Map ein Objekt des Werts direkt als Member haben (z.B. als Optimierung, um standardkonstruierte Objekte von einem Prototypen zu kopieren).

    Willst du deinen Baum nicht in eine (oder zwei) Klassen kapseln? Dann würde das Problem wegfallen, zudem wärst du auch freier, sonstige Methoden bereitzustellen oder das Interface der std::map einzuschränken.

    class ValueTree;
    
    class FieldTree
    {
    	public:
    		ValueTree& operator[] (TVALUE key)
    		{
    			return myMap[key];
    		}
    
    	private:
    		std::map<TVALUE, ValueTree> myMap;
    };
    
    class ValueTree
    {
    	public:
    		FieldTree& operator[] (TFIELD key)
    		{
    			return myMap[key];
    		}
    
    	private:
    		std::map<TFIELD, FieldTree> myMap;
    };
    


  • Eigentlich ist es zu trivial. Es ist eine map die ich brauche, das Ganze wird innerhalb einer Filterklasse als interne Repräsentanz verwendet.
    Eigene Klassen zu bauen, war ein Ansatz, aber stellte sich als überflüssig heraus und aus sportlichem Ergeiz dachte ich, es müsste doch auch nur mit typedefs gehen.
    Aber es geht scheinbar nicht.

    Eigentlich ist es keine Rekursion Der Baum sieht so aus und ist in sich immer nur eine MAP. Das es keine Rekursion ist, sieht man ja daran, dass es mit meiner Hilfstruktur geht.

    Was ich darstellen sieht in etwa so aus

    Feld Wert Feld Wert Feld Wert Feld Wert
    1    1    10   1    100  1
                   2
                   3    101  1
                        102  2
                             3
    2    2    20
    3    1
    3    2
    3    3    10   1
                   2
                   2
    

    Eigenlich entsteht so ein Baum. Wobei ein Feld immer nur Werte Konten hat und ein Wert immer nur Feld Knoten hat.

    Hintergrund:
    Dieser Baum dient der schnellen Abfragetechnik ob bestimmte Bedingungen (Zustände) in einem Objekt vorhanden sind.



  • Martin Richter schrieb:

    Eigentlich ist es keine Rekursion Der Baum sieht so aus und ist in sich immer nur eine MAP. Das es keine Rekursion ist, sieht man ja daran, dass es mit meiner Hilfstruktur geht.

    Es geht nur um den Datentyp. C++ kommt nicht klar damit, dass die Maps sich gegenseitig einschliessen. Wenn du den resultierenden Typen nämlich auschreiben würdest, wäre er unendlich lang.

    Martin Richter schrieb:

    Eigenlich entsteht so ein Baum. Wobei ein Feld immer nur Werte Konten hat und ein Wert immer nur Feld Knoten hat.

    Okay, also im Prinzip ein bipartiter Graph. Aber wie gesagt: Die Datenstruktur selbst ist nicht das Problem (da es ja mit deiner struct oder meiner Klasse geht).

    Ich sehe aufgrund des beschriebenen Problems keine Möglichkeit, das direkt zu machen. Du willst ja wahrscheinlich keine Zeiger benutzen. Tut mir leid für deinen sportlichen Ehrgeiz, aber du musst wohl zur Klasse greifen. 😉

    Vielleicht gibts auch irgendeinen Template-Meta-Hack, aber ob dir das lieber wäre? 🙂


Anmelden zum Antworten