Collection wie Z.B Map( key, value ) und value mit unterschiedlichen Datentypen ?



  • Hallo liebe C++ - Gemeinde,

    ich habe ein Problem und hoffe, dass hier jemad mir helfen kann.

    ich brauche eine Collection wie Z.B Map( key, value ).

    Mein key ist String und value hat unterschiedliche Datentypen:
    unsigned char, signed char,
    unsigned short, signed short,
    unsigned long, signed long usw.

    gibt es solche Collection bei c++ , die so was aufnehnen kann. 😕 😕

    danke für alle



  • Hi,

    im "Standardumfang" nicht, das widerspräche der Typsicherheit (zur Compilezeit).
    Also wenn ich mir so Deine "Auswahl" ansehe, scheint mir, dass Du mit einer std::map<std::string, long> wohl ganz gut bedient wärst ;).

    Alternativ kannst Du natürlich auch eine entsprechende union nehmen...(Wobei das eigentlich wiederum der Typsicherheit widerspricht).

    Gruß,

    Simon2.



  • Danke für dir schnelle Antwort.

    meinest Du, wenn ich std::map<std::string, long> dekl., nehmt er auch unsigned char, signed char usw. 🙄 🙄 ? Ich werde es probieren.

    gibt es in C++ welche Collection zum Beispiel List od. anderes( muss nicht key-value sein ), die unterchiedliche Datentypen aufnehmen kann?

    danke und dankeschön



  • Nicht direkt. Du kannst höchstens einen Datentyp wählen, in dem du all deine gewünschten Typen hineinbekommst oder du verwendest Zeiger und machst eine Liste von void*. Da gehen dir allerdings die Typinformationen verloren.
    Alternativ gibt es noch solche sachen wie boost::any oder boost::variant.
    Die Frage hier ist eher, warum brauchst du sowas? Lässt sich die Notwendigkeit einer solchen Liste durch ein besseres Design erledigen?



  • In C++ gibt es garkeine Collections sondern nur Container.
    Der Unterschied ist mehr als nur das Wort. Eine Collections enthält selbst keine Elemente sondern nur Referenzen/Zeiger/Verweise auf Elemente. Ein Container enthält die Elemente selbst. Und so wie die Container in C++ implementiert sind können die eben nur Elemente eines Typs speichern.
    Der Ausweg ist sich selbst eine Art Collection zu basteln, indem man einen Container von Pointern verwendet:

    struct Element
    {
        virtual ~Element() {}
    };
    
    struct ElementA : Element {};
    struct ElementB : Element {};
    
    std::vector<Element*> v;
    

    Solange die Lifetime der Objekte "ausserhalb" geregelt wird ist das OK.
    Wenn man allerdings möchte dass der Eintrag im "Collection-Container" die Elemente am Leben erhält bietet es sich an eine Smart-Pointer Klasse wie boost::shared_ptr zu verwenden:

    struct Element
    {
        virtual ~Element() {}
    };
    
    struct ElementA : Element {};
    struct ElementB : Element {};
    
    std::vector<boost::shared_ptr<Element> > v;
    

    Natürlich kann man theoretisch auch ohne gemeinsame Basisklasse arbeiten (z.B. mit shared_ptr<void>), bloss muss man dann einen passenden Typ für jedes Elementes wissen -- dynamic_cast funktioniert ja dann nichtmehr, bleibt also nurmehr static_cast, und static_cast mit void* als Quelle funktioniert nur richtig wenn man auf genau den Typ zurückcastet von dem ursprünglich auf void* gecastet wurde.

    ---

    Die Varianten mit union/boost::variant/boost::any sind natürlich auch OK, man muss halt immer wissen was man braucht, und dann entscheiden was in der bestimmten Situation passend ist.



  • Danke für alle,

    Ich werde es probieren.



  • rena schrieb:

    Danke für alle,

    Ich werde es probieren.

    Hi,

    vielleicht solltest Du auch mal erwägen, nicht zu versuchen, "Java in C++ zu programmieren". C++ "tickt" einfach anders und dazu gehört auch das Konzept typsicherer Container....
    Musst Du wirklich in Deinen Container unterschiedlichste Sachen packen (und hinterher wieder "auseinanderfriemeln") ?

    Gruß,

    Simon2.


Anmelden zum Antworten