verschiedene datentypen in einem std::vector<>



  • Ich habe einen std::vector<> in dem ich daten speichere.
    Leider können diese variablen vom typ INT UINT LONG STRING oder CHAR sein.
    Nun möchte ich jedoch nicht für jeden datentyp einen eigenen vector erstellen, sondern möchte alle in diesem einen vector speichern.

    also folgendes soll erreicht werden:

    std::vector</*ptr auf beliebigen datentyp*/> MyVec;
    int i = 53;
    char c = "h";
    std::string str = "hallo world";
    MyVec.pushBack(&i);
    MyVec.pushBack(&c);
    MyVec.pushBack(&str);
    int i2 = (int)*MyVec[0];
    char c2 = (char)*MyVec[1];
    const char* str2 = MyVec[2]->c_str();
    

    Gibt es überhaupt eine möglichkeit in C++ um einen pointer auf einen beliebigen datentypen zu speichern?



  • std::vector<void *> MyVec;
    

    Ist aber schlechte Stil und sollte vermieden werden.



  • pointer auf void ? okay, stil ist vielleicht nicht der beste, aber ist in diesem fall nicht zu vermeiden.



  • wie wäre das dann wenn ich einen char* übergeben will?
    muss ich dann einen pointer auf einen pointer setzen? ( void** )



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum WinAPI in das Forum C++ (auch C++0x und C++11) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • std::vector<boost::any>
    


  • Du kannst entweder den char * direkt übergeben oder die Adresse davon, dem void * und dem Vektor ist das egal. Das Problem ist, dass du im Nachhinein noch wissen musst was es war.
    Du musst übrigens erst casten und dann dereferenzieren.

    int i2 = (int)*MyVec[0]; //funktioniert nicht, weil void * nicht dereferenzierbar sind
    int i2 = *((int *)MyVec[0]);
    

    Eine Alternative ist union zu verwenden.

    union Mytype{
    INT i;
    UINT u;
    LONG l;
    STRING s;
    CHAR c;
    };
    std::vector<Mytype> vec;
    int i = 53;
    Mytype mt;
    mt.i = i;
    vec[0] = mt;
    ...
    int i2 = vec[0].i;
    

    boost hat trotz großer Anstrengungen bei mir nie funktioniert, aber sehr viele Leute schwören drauf.


  • Mod

    Die wichtige Frage bei Fragen dieser Art ist wie immer: WARUM?



  • SeppJ schrieb:

    Die wichtige Frage bei Fragen dieser Art ist wie immer: WARUM?

    Frag ich mich auch gerade.

    Ansosnten:
    Verwende Boxing für die Datentypen.
    Zuerst machst du eine abstrakte Basisklasse Box mit get und set.
    Dann leitest du diese Klasse für alle deine Datentypen ab.
    Jetzt kannst du deinen Vektor vector<Box*> myVector; verwenden, der alle deine Datentypen speichert.
    Problem ist natürlich beim Auslesen, dass du nicht weißt, welcher Datentyp myVector[4] nun ist.
    Kannst ja noch einen Enum der Basisklasse hinzufügen, enum Typ {INT, DOUBLE, usw...}, der dann in jeder abgeleiteten Klasse gesetzt wird, den du dann abfragst:

    if(myVector[4].typ==DOUBLE)
    {mach irgendwas für double}
    else if(myVector[4].typ==INT)
    {...}

    Schön ist das natürlich nicht, aber ich weiß auch nicht warum du verschiedenste Wertetypen in einem vector haben möchtest.
    Alternative wäre bei Zahlen natürlich, alles in einen vector<double> zu stecken.



  • nwp3 schrieb:

    boost hat trotz großer Anstrengungen bei mir nie funktioniert, aber sehr viele Leute schwören drauf.

    was kann denn da nicht funktionieren ? bosot::any z.b. ist header-only, dass heißt, du musst nur die header einbinden, mehr musst du nicht machen (das ist nicht bei allen boost-libs so). das setzt natürlich voraus, dass du mit deinem compiler umgehen kannst und du musst wissen, was du machst.



  • okay, ich glaub ich hab jetzt erstmal nen paar lösungsansätze 👍
    ich brauche es später für ein eigenes dateiformat. das programm soll dann später die variablen in einer liste speichern (egal welches format die variable hat).
    diese liste wird dann vom programm bearbeitet und wieder abgespeichert.

    nebenbei, mein dateiformat sieht bis jetzt so aus (zumindest grob, bin heute erst angefangen):

    [ARC_FILE_1_1]
    
    BEGIN_DATABASE[MyDataBase1]
       INT MyInt1 [645]
       UINT MyUInt1 [54]
       STR MyStr1 ["hello world"]
       WSTR MyWStr1 ["hello world"] 
    END
    


  • gamer8o4 schrieb:

    okay, ich glaub ich hab jetzt erstmal nen paar lösungsansätze 👍
    ich brauche es später für ein eigenes dateiformat. das programm soll dann später die variablen in einer liste speichern (egal welches format die variable hat).
    diese liste wird dann vom programm bearbeitet und wieder abgespeichert.

    nebenbei, mein dateiformat sieht bis jetzt so aus (zumindest grob, bin heute erst angefangen):

    [ARC_FILE_1_1]
    
    BEGIN_DATABASE[MyDataBase1]
       INT MyInt1 [645]
       UINT MyUInt1 [54]
       STR MyStr1 ["hello world"]
       WSTR MyWStr1 ["hello world"] 
    END
    

    achso, na bei einem Dateiformat kannst ja alles nach string konvertieren und so auch speichern. Wäre vermutlich das einfachste wenn die Datei im Textformat existieren soll.



  • achso, na bei einem Dateiformat kannst ja alles nach string konvertieren und so auch speichern. Wäre vermutlich das einfachste wenn die Datei im Textformat existieren soll.

    wäre vermutlich das einfachste zum speichern und laden (genau so hab ich es in früheren projekten auch gelöst 😉 ), jedoch ist das problem, dass ich die variablen bearbeiten will und damit ich sie nicht bei jeder änderung in von string in z.B int und zurück konvertieren muss speichere ich sie doch lieber direkt im richtigen format in meinem vector ab.



  • @dfsdfsdf: Der Ansatz ist letztenendes nicht besser als void * . vector<double> ist keine Alternative, weil er auch Zeichenketten drin speichern möchte.

    gamer8o4 schrieb:

    wäre vermutlich das einfachste zum speichern und laden (genau so hab ich es in früheren projekten auch gelöst 😉 ), jedoch ist das problem, dass ich die variablen bearbeiten will und damit ich sie nicht bei jeder änderung in von string in z.B int und zurück konvertieren muss speichere ich sie doch lieber direkt im richtigen format in meinem vector ab.

    "Im richtigen Format"? Und was wäre das dann? Wenn du keine separaten Vektoren und kein boost nutzen kannst/willst, dann wirst du vermutlich "stringstreamen" müssen. Wenn du dich für Pointer auf void entscheidest, machst du dir das Leben einfacher, wenn du dir den Datentyp zu jedem Element vermekst (evtl. std::list<std::pair<std::string, void *> > ).

    Nur ganz am Rande: Deutsch ist nicht deine Muttersprache, oder?


Log in to reply