Über Datentypen interieren



  • Schau dir mal das Video C++ Seasoning von Sean Parent an. Sein Anwendungsfall ist zwar ziemlich konkret, aber vllt lässt sich das auf deinen Fall anpassen.



  • @booster
    Ein Beispiel:

    #include <vector>
    #include <variant>
    #include <string>
    #include <iostream>
    
    using MySpecVariant = std::variant<int, double, std::string>;
    
    // KKDC: Kurzer Knackiger Demo Code
    int main() 
    {
        std::vector<MySpecVariant> L;
            
        L.push_back("Hallo");
        L.push_back(1);
        L.push_back(3.4);
        L.push_back("Welt");
        std::for_each(std::begin(L), std::end(L), [](const MySpecVariant& v) {
           if (std::holds_alternative<int>(v))
           {
               std::cout << "Integer: " << std::get<int>(v) << "\n";
           }
           else if (std::holds_alternative<double>(v))
           {
               std::cout << "Double: " << std::get<double>(v) << "\n";
           }
           else if (std::holds_alternative<std::string>(v))
           {
               std::cout << "String: " << std::get<std::string>(v) << "\n";
           }
        });
        return 0;
    }
    


  • @Quiche-Lorraine sagte in Über Datentypen interieren:

    Dazu muss ich dann aber für jeden Datentypen einen Wert anlegen. Da das bei mir aber keine rudimentären Datentypen sind sondern komplexe ist das mit dem Anlegen gar nicht so einfach. Des Weiteren sind manche Abstrakt und können gar nicht konstruiert werden.

    Ich möchte ja nur über die Datentypen iterieren.



  • @booster Irgendwie machst du da was komisches... Was soll den ein Datentyp ohne dazugehörige Instanz sein und was willst du davon abhängig machen?
    Für jeden Datentyp der in dem JSON File vorkommt? Oder, woher kommt der Datentyp? Wie hast du den "Typ" vorliegen?
    Mir ist gerade unklar was du genau warum machen möchtest. Vielleicht bin ich aber gerade einfach zu müde.



  • @booster
    Anhand deiner Beschreibung verstehe ich nicht wo du da über Datentypen iterieren wollen würdest.
    Das klingt eher danach als ob deine Klassen ein paar virtuelle Funktionen gebrauchen könnten.

    Oder vielleicht suchst du abstrakte Factories?
    Also sowas

    class MyAbstractFactory {
    public:
        virtual unique_ptr<CommonBaseClass> createFromJson(JsonThing const& json) = 0;
    };
    

    Und dann pro Datentyp eine konkrete Factory die von MyAbstractFactory abgeleitet ist.



  • Noch ein Versuch... In der Json stehen die Namen der Typen der Klasse als vollständiger Name drin.

    Vereinfacht

    class mynamspace::classA
    class mynamspace::classB
    class mynamspace::classC
    class mynamspace::classD
    class mynamspace::classE

    nun suche ich aus der Json den Typ classB und ClassD und möchte beide unterschiedlich behandeln

    Natürlich könnte ich nun ein vector machen der "classB" und "classD" als string enthält darüber iterieren (nur ein Beispiel mit den 2 Klassen) und dann mit einem switch case die beiden Typen unterschiedlich handeln.

    Aber ich dachte wieso als string speichern wenn ich die Datentypen speichern kann (bzw könnte) und dann nicht per switch case unterscheiden sondern per konkreter Implementierung.

    @hustbaer
    Ja das kann ich auch machen. Aber das löst ja nicht mein Problem. Ich möchte ja im Json nur nach bestimmten Datentypen suchen die darin abgelegt wurden.



  • Also mir gehts ja Hauptsächlich darum dass ich das switch case vermeide.
    Wenn ich mir nun in einem vector per typeid(classB).name den Namen der Klasse ablege,
    wie kann ich dann unterschiedliche Funktionen aufrufen. Je nachdem ob classB oder classD.



  • Naja, wie @SeppJ oben schon mal schrieb, zur Laufzeit gibt es keien Typen mehr....

    Wenn du kein Switch Case haben möchtest, wäre vlt ein Look Up Table für die nötigen Funktionen was für dich. Irgendwie was in dieser Art: std::map<std::string, std::function<void()>>

    #include <iostream>
    #include <string>
    #include <map>
    #include <functional>
    
    int main()
    {
      std::map<std::string, std::function<void()>> lut{
          {"classA", []() {std::cout << "class A \n"; }},
          {"classB", []() {std::cout << "class B \n"; }}
      };
      lut["classA"]();
      lut["classB"]();
    }
    

    Edit: Für typeid() braucht man doch auch eine Instanz des Typen den man nachgucken möchte, oder?



  • @Schlangenmensch

    Ja Lockuptabelle wäre auch eine Möglichkeit. Das andere hätte mir zwar besser gefallen.
    So muss ich nun für jeden Typen eine Funktion mit eigenem Namen erstellen und in die Lockuptabelle eintragen.

    Bei der anderen Lösung hätte ich dann immer den gleichen Namen der Funktion nur mit Templateparameter und ich müsste nicht immer noch die Lockuptabelle füllen. Aber wenns nicht geht, dann gehts nicht 🙂

    @Schlangenmensch sagte in Über Datentypen interieren:

    Edit: Für typeid() braucht man doch auch eine Instanz des Typen den man nachgucken möchte, oder?

    mit typeid hatte ich auch getestet. Aber die Info kann ich auch nicht in einem vector bzw Variable speichern.



  • @booster sagte in Über Datentypen interieren:

    Und dann diese Daten unterschiedlich je nach Typ (nicht alle in der Json Struktur nur ein paar) handeln.

    Das ist doch klassische Fall für Polymorphie. Wenn es nicht über virtuelle Funktionen gemacht wird, dann halt über Compilezeit Polymorphie. Man kann mit einer Typelist (Modern C++ Design sollte man mal gelesen haben, auch wenn es für C++98 ist) über die Typen iterieren.

    Als Beispiel kannst Du z.B. diesen Link nehmen.



  • @john-0 Ich sehe noch nicht, wie das hilft, wenn die "Typen" erst zur Laufzeit als String vorliegen. Das ist zumindest mein Verständnis, des Problems hier.

    Wenn die Typen natürlich schon zur Compiletime bekannt sind, dann go for it 😉



  • @john-0 sagte in Über Datentypen interieren:

    Das ist doch klassische Fall für Polymorphie.

    Im Grund ja. Natürlich kann ich die classB und classD von einer abstracten Basisklasse erben lassen die dann die Funktionen implementieren. Das ist ja das was auch Hustbear gemeint hat mit seiner Abstract Fatory. Wenn ich ihn richtig verstanden habe.

    @Schlangenmensch sagte in Über Datentypen interieren:

    Wenn die Typen natürlich schon zur Compiletime bekannt sind, dann go for it

    Ja du hast es erkannt daran liegt das Problem. Die Typen sind erst zur Laufzeit bekannt.



  • @booster sagte in Über Datentypen interieren:

    Ja du hast es erkannt daran liegt das Problem. Die Typen sind erst zur Laufzeit bekannt.

    Naja, Du beschreibst das äußerst umständlich. Vor allem wenn Du Dinge serialisieren willst, liegen sie als Objekte im Speicher vor. D.h. die Typen sind zur Compilezeit bekannt. Üblicherweise hat man in C++ das Problem beim umgekehrten Schritt bei der Deserialisierung sprich man bekommt einen Strom an Text und will daraus wieder Objekte bauen. Letzteres ist als Reflection bekannt.



  • @john-0 sagte in Über Datentypen interieren:

    Naja, Du beschreibst das äußerst umständlich.

    Wenn du meinst.

    Das Problem scheint noch nicht verstanden zu sein. Aus dem Text Objekte zu bauen ist auch nicht das Problem.

    Nochmals. Wir machen das etwas abstrakter.

    Wir haben eine Liste.

    EintragA
    EintragB
    EintragC
    EintragD
    EintragA
    EintragB
    EintragC
    EintragD

    Nun möchte ich aus der Liste 2 Einträge raus suchen und unterschiedlich behandeln
    Also halte ich mir eine zweite Liste in der ich sage welche Einträge ich suchen möchte.

    Iteriere über beide Listen drüber und vergleiche und wenn ich den passenden Eintrag in der Liste gefunden habe muss ich etwas bestimmtes machen mit dem Eintrag.

    So weit so gut. Die Idee war nun da die Einträge einem Datentypen entsprechen, also dessen Namen, ich keine Liste mit Namen speichere sondern eine Liste mit Datentypen.

    Die Behandlung der beiden unterschiedlichen Einträge wäre dann durch Polymorphie oder Templateprogrammierung möglich.

    Immer noch unverständlich. Wenn ja. Dann ists halt so. Sorry.



  • Du beschreibst dein Problem nicht präzise. Du sagst, dass du

    • über Datentypen iterieren möchtest. Möchtest du aber nicht, du möchtest eine Fallunterscheidung für strings. Das, was du als Datentyp bezeichnest, ist letztendlich doch nur eine Eigenschaft eines JSON Objekts.
    • eine Liste hast. Hast du aber nicht, du hast ein JSON Dokument, in dem bestimmte Objekte einen Namen haben.

    Wenn du uns jetzt verrätst, was du konkret mit zwei Einträgen machen möchtest kann man dir vielleicht helfen.



  • @DocShoe

    ok ich bekomme es nicht rüber. Bzw @Schlangenmensch hat mich verstanden

    Ich machs mit der Loockup Tabelle das wird das einfachste sein.

    @DocShoe sagte in Über Datentypen interieren:

    Wenn du uns jetzt verrätst, was du konkret mit zwei Einträgen machen möchtest kann man dir vielleicht helfen.

    Was ich mit den Einträgen machen will ist doch völlig egal. Es geht mir doch nur darum dass ich die beiden Fälle unterscheiden kann. Egal ich lass es. Passt danke.



  • @booster

    Ne, eben nicht. Du beschreibst deine Anforderung so konfus, dass niemand versteht, was du eigentlich machen möchtest. Du bist gedanklich ein paar Schritte weiter und beschreibst das Problem, das du nach diesen Schritten hast. Wenn du uns erklärst was du eigentlich vorhast kann man dir helfen. Für mich hört sich das jedenfalls nach dem XY Problem an.

    Im Moment verstehe ich das so, dass du verschiedene JSON Objekte aus dem Dokument heraussuchen und unterschiedlich behandeln möchtest. Zur Fallunterscheidung dient dazu eine Eigenschaft des JSON Objekts, das du als "Datentyp" bezeichnest.



  • @DocShoe sagte in Über Datentypen interieren:

    @booster

    Ne, eben nicht. Du beschreibst deine Anforderung so konfus, dass niemand versteht, was du eigentlich machen möchtest.

    Gut dann tuts mir leid dass ich das nicht so beschreiben kann dass du das verstehst. Oder es allgemein zu konfus ist. Wie auch immer

    @DocShoe sagte in Über Datentypen interieren:

    Zur Fallunterscheidung dient dazu eine Eigenschaft des JSON Objekts, das du als "Datentyp" bezeichnest.

    Nein tut es nicht.



  • @booster sagte in Über Datentypen interieren:

    Wenn du meinst.

    Definitiv!

    Wir haben eine Liste.

    Was für eine Liste? (Wenn man sich den kompletten Thread durchliest, kann man entnehmen, dass es wohl Namen von Klassen in der Liste sind.) Warum steht das bei der Beschreibung nicht dabei? Du redest von Iterieren über Typen, meinst aber Namen von Typen. Das ist eben kein unwesentlicher Unterschied.

    EintragA
    EintragB
    EintragC
    EintragD
    EintragA
    EintragB
    EintragC
    EintragD

    Nun möchte ich aus der Liste 2 Einträge raus suchen und unterschiedlich behandeln

    Reflection Problem, Factory nehmen, die liefert dann für jeden Namen ein Objekt (Functor o.ä.) zurück, was dann irgend was macht, was Du vorher definiert hast.



  • @john-0 sagte in Über Datentypen interieren:

    ja nochmals. Ihr könnt mich nun auch aufs übelste verurteilen dass ich das nicht so beschreiben kann das ihr euch das vorstellen könnt. Wollt ihr da nun weiter drauf rum hacken.

    @john-0 sagte in Über Datentypen interieren:

    Warum steht das bei der Beschreibung nicht dabei?

    Tut es sogar an mehreren Stellen.

    Hier zum Beispiel

    @booster sagte in Über Datentypen interieren:

    Noch ein Versuch... In der Json stehen die Namen der Typen der Klasse als vollständiger Name drin.
    Vereinfacht
    class mynamspace::classA
    class mynamspace::classB
    class mynamspace::classC
    class mynamspace::classD
    class mynamspace::classE

    Aber egal.

    Ich möchte das Objekt aus der Json nicht wieder deserialisieren. Ich möchte nur wissen ob sich die beiden Einträge in der Json befinden nichts weiter.

    Wenn sich der Eintrag class mynamspace::classB im Json befindet dann führe Funktion X aus
    Wenn sich der Eintrag class mynamspace::classD im Json befindet dann führe Funktion Y aus


Anmelden zum Antworten