Frage zu typedef



  • Guten Morgen 🙂

    Ich habe schon wieder eine Frage 😃

    Es geht dabei um das schöne Stichwort typedef. Da ich es bisher noch nie wirklich gebraucht habe, hab ich damit keine Erfahrung, weiß aber, was es macht.

    Ich würde gerne wissen, ob/wie ich damit einen etwas komplexeren Datentyp deklarieren kann, der sich aus unterschiedlichen Standarddatentypen zusammensetzt.

    Als Beispiel möchte ich ein Schema für IDs deklarieren. Eine ID soll die Form (Char)(int)-(int)-(int) haben, z.B. A23-12-02 oder P01-451-134.

    Kann ich diese Form überhaupt mit typedef definieren?
    Und falls ja, wie schaut es mit Vergleichen aus, z.B. in if-abfragen und als key bei maps?

    Viele Grüße
    Cherup



  • also mit google findest du 1Mio Seite die das genau erklären - ist das schon zu viel

    google typedef struct



  • Danke,

    das mit struct habe ich zwar schon gesehen, aber ich habe wohl noch nicht ganz verstanden, wie ich dann mit typedef umgehen kann.
    Oder du hast den Kern meiner Frage nicht getroffen.

    Wie muss ich dann das struct aufbauen, damit ich Vergleiche anstellen kann? Kann ich die so konstruierte ID einfach mit einem ID-Wert vergleichen wie ich z.b. zwei ints miteinander vergleiche?

    Im Endeffekt möchte ich ja sowas wie

    ID ID1 = A23-12-02; //ID ist offensichtlich der Datentyp
    ID ID2 = P01-451-134;
    ID ID3 = G04-43-01;
    map<ID,string> IDmap;
    map[ID3] = "ID3";
    
    if(ID1 == ID2) return IDmap[ID3];
    

    schreiben können.

    Wie schon geschrieben, ich habe mit typedef keine Erfahrung. Deshalb frage ich hier, damit ich von Anfang an eine klare und vor allem korrekte Vorstellung habe, wie ich mit typedef umgehen muss und was und auf welche Weise ich damit anfangen kann. Wissen kann ich mir bei Google erst dann effektiv zusammensuchen, wenn ich eine klare Vorstellung davon habe, WAS ich suche und WAS ich damit anfangen will.
    Insofern JA, das ist schon zuviel, weil ich schlicht nicht wußte, das ich einen zusammengesetzten Datentyp mit einem struct realisieren kann.
    Sry für die teilweise etwas harsche Antwort, aber es kommt sehr überheblich rüber und darauf reagiere ich gereizt. Ein einfaches "google mal nach typedef struct" hätte es auch getan, uns beiden Zeit erspart und wäre sehr viel freundlicher und konstruktiver...

    VG
    Cherup



  • Ich glaube, dass Du mit "typedef" nicht Dein Ziel erreichst.

    Zitat: "Als Beispiel möchte ich ein Schema für IDs deklarieren. Eine ID soll die Form (Char)(int)-(int)-(int) haben, z.B. A23-12-02 oder P01-451-134."

    Das "Schema" für die IDs würde ich als Klasse bzw. Struct mit Attributen und Operatoren bauen. Du musst dir ausdenken, wie eine Sortierung aussehen soll und dann die benötigten Operatoren dementsprechend ausgestalten.



  • Gast3 schrieb:

    also mit google findest du 1Mio Seite die das genau erklären - ist das schon zu viel

    google typedef struct

    Wozu braucht man in C++ typedef struct?



  • Warum nimmst du an, dass du typedef benötigst?
    typedef führt nur einen weiteren Namen ein, es schafft aber nichts wirklich neues.



  • Nun, ich dachte eigentlich, das ich damit einen neuen Datentyp "erstelle", aber du hast recht, wenn ich ein global verfügbares struct baue, ist das ja unnötig und auf gut deutsch, totaler Blödsinn :D.

    Jetzt überlege ich gerade, wofür man denn typedef überhaupt braucht. Es gibt Sonderfälle, bei denen man eine Kompatibilität des Codes für verschiedene Rechner/Systemarchitekturen mit typedef herstellen kann, aber sonst?

    Ich bin grad etwas vernagelt, wenn ich ein struct baue und darin den Operator "==" überlade, dann müsste ich doch problemlos mit if vergleichen können, oder?
    Aber wie ist das mit maps, bei denen das Struct als key verwendet wird? FUnktioniert das dann auch?

    Helmut.Jakoby schrieb:

    Du musst dir ausdenken, wie eine Sortierung aussehen soll und dann die benötigten Operatoren dementsprechend ausgestalten.

    Was genau meinst du mit Sortierung? Das Schema der ID oder nach welchen Regeln die einzelnen Werte vergeben werden?

    Danke für eure deutlich konstruktiveren Antworten 🙂

    VG
    Cherup



  • Wozu braucht man in C++ typedef struct?

    braucht man nicht - waren nur Stichworte - in einer unglücklichen Reihenfolge 🙂

    Wie schon geschrieben, ich habe mit typedef keine Erfahrung. Deshalb frage ich hier, damit ich von Anfang an eine klare und vor allem korrekte Vorstellung habe, wie ich mit typedef umgehen muss und was und auf welche Weise ich damit anfangen kann. Wissen kann ich mir bei Google erst dann effektiv zusammensuchen

    du tätigst Annahmen über das Verhalten von etwas was du nicht kennst - z.B. das man mit typedef structuren definieren könnten - machst dir aber nicht mal die Mühe den ersten Treffer bei google zu "c++ typedef" oder sowas zu lesen? - ich hätte es wohl noch unfreundlicher formulieren sollen

    hier die 2 ersten Treffer - danach ist alles klar und du kannst weiterfragen
    http://www2.informatik.uni-halle.de/lehre/c/c_typdef.html
    http://www2.informatik.uni-halle.de/lehre/c/c_struct.html



  • Ich bin mir nicht ganz sicher, aber ich glaube dass Du für std::map einen operator< haben musst, damit die IDs einsortiert werden können. Ich würde der Vollständigkeit halber bei einer Klasse für die IDs die Operatoen '==', '!=', '<', '<=', '>' und '>=' definieren.
    Mit Sortierung meine ich, dass z.B. die ID "A23-23-34" ggf. vor "P01-451-134" einsortiert sein soll; also die zweite ID "größer" ist.



  • Gast3 schrieb:

    braucht man nicht - waren nur Stichworte - in einer unglücklichen Reihenfolge 🙂

    Nun, ich hab eben genau danach bei google gesucht (und auch etwas gefunden).
    Jetzt bin ich etwas klüger. Was genau structs sind, wußte ich bereits, und ich wußte, das mit typedef ein Aliasname für einen Datentyp erstellt wird.
    Was ich noch nicht begriffen hatte war die Tatsache, das ein Aliasname keine Datentyp-Definition ist. Ich hatte also noch keine klare Vorstellung davon was typedef macht.
    Also mache ich Annahmen, basierend auf (falschen) Vermutungen, wie eben der Vermutung, dass man mit typedef zusammengesetzte Datentypen konstruieren kann.

    Cherup schrieb:

    Kann ich diese Form überhaupt mit typedef definieren?

    Ich hatte deshalb auch gefragt, ob das überhaupt möglich ist.

    Ganz ehrlich, wäre dir eine Frage wie "Hi, ich hab keine Ahnung, was typedef macht, erklärt mir das!" lieber? Mir nicht und ich würde ähnlich reagieren wie du.

    VG
    Cherup



  • @Helmut.Jakoby
    Danke,

    ich werde das mal ausprobieren.
    Jetzt habe ich immerhin schon einen konkreten Lösungsansatz 🙂



  • Ganz ehrlich, wäre dir eine Frage wie "Hi, ich hab keine Ahnung, was typedef macht, erklärt mir das!" lieber? Mir nicht und ich würde ähnlich reagieren wie du.

    deine 1. Frage hatte mehr oder weniger diesen Titel/Inhalt

    die typedef (und daraus folgend struct) Frage hättest du dir einfach vorher zu 100% selbst mit google beantworten können und hier nur deine konkrete map-Frage gestellt - und genauso habe ich es auch in meinem 1. Post geschrieben

    und viel weniger als mit google nach typedef suchen und lesen kann man eben nicht erwarten

    btw: hast du noch nicht abstrakt erklärt was du erreichen willst - es könnte eine ganz andere leichterer Lösung geben



  • Gast3 schrieb:

    deine 1. Frage hatte mehr oder weniger diesen Titel/Inhalt

    die typedef (und daraus folgend struct) Frage hättest du dir einfach vorher zu 100% selbst mit google beantworten können

    Damit hast du recht. Hatte auch schon nach typedef gegoogelt, aber hatte es halt nicht richtig verstanden.

    Und was ich erreichen wollte? Grundsätzlich wollte ich erstmal typedef verstehen und was ich damit machen kann. Ausserdem wollte ich wissen wie ich eigene Datentypen erstellen kann. Hätte ich etwas mehr nachgedacht wäre mir eingefallen, dass Klassen und structs schon eigene zusammengesetzte Datentypen sind 🙄
    Die Lösung liegt im Endeffekt in der Operatorenüberladung für einen struct/ eine Klasse.
    Ich versuche mich zurzeit in das Thema Templates und generische Programmierung einzuarbeiten.



  • Ich greife diesen Thread nochmal für eine weitere Frage auf.

    Kurzform: Das Ziel ist, dass ich am Ende einen Baum/Container/... habe, der beliebig viele Werte eines beliebigen Typs speichern kann.

    Beschreibung:
    Stichwort Templates.
    Ich habe ein Struct für die ID geschrieben und die Operatoren "==", "!=, "<", "<=", ">" und ">=" überladen.
    Das Schema der ID ist wie im Beispiel (char)(int)(int)(int).

    Jetzt möchte ich alle IDs in einem Baum speichern. Jeder Knoten-Grad steht für den entsprechenden Grad des ID-Schemas (Ich hoffe, es ist klar was ich meine :D) und jeder Knoten speichert einen Wert und kann auf beliebig viele Knoten des nächsten Grades zeigen.
    Die Wurzel hat also an sich gar keinen Wert (bzw einen beliebigen), die Knoten des Grades 1 haben nur Chars als Wert und die Knoten der Grade 2-4 haben einen int-Wert.

    Jedes Struct bekommt als Template-Parameter den Typ für seinen eigenen Wert (T1) und den Typ des Wertes des nächsten Knotens (T2).
    Die nächsten Knoten werden als pointer in einer map gespeichert.

    Der Compiler meckert aber beim Build rum und ich versteh auch warum.
    Ich weiß aber nicht, wie ich das sinnvoll beheben kann bzw. ob das überhaupt in der Form möglich ist, wie ich mir das vorstelle/erhoffe...

    Fehler/Problem:
    Mit addNode(IDTreeNode* node) wird ein neuer Knoten an den aktuellen angehängt.
    Allerdings müssen ja in der Funktion und in der map die template-Parameter für den anzuhängenden Node mit angegeben werden.
    Ich möchte den Baum aber so Typ-unabhängig wie möglich haben. Also muss ich quasi die Typen des anzuhängenden Knotens wissen, bevor ich sie weiß 😕 .

    Minimalbeispiel:
    Der TestCode schaut bis jetzt wie folgt aus:
    "main.cpp":

    #include "templatetest.h"
    
    int main(int argc, char *argv[])
    {
        TemplateTest* test = new TemplateTest();
        return 0;
    }
    

    "templatetest.h":

    #include <map>
    
    using namespace std;
    
    template <typename T1, typename T2>
    struct IDTreeNode{
        IDTreeNode<T1,T2>(T1 value);
    
        bool existNode(T2 value);
    
        void addNode(IDTreeNode* node); //Funktioniert nicht
        //void addNode(IDTreeNode<T2,T2>* node); //Funktioniert
    
        T1 getValue();
        IDTreeNode* getNode(T2 value);
    private:
        T1 myValue;
        map<T2, IDTreeNode*> myNodes; //Funktioniert nicht
        // map<T2, IDTreeNode<T2,T2>*> myNodes; //Funktioniert
    };
    
    class TemplateTest
    {
    public:
        TemplateTest();
    };
    

    und "templatetest.cpp":

    #include "templatetest.h"
    
    TemplateTest::TemplateTest()
    {
        IDTreeNode<char,int>* NodeStart = new IDTreeNode<char,int>('A');
        IDTreeNode<int,int>* Node1 = new IDTreeNode<int,int>(1);
        IDTreeNode<int,int>* Node2 = new IDTreeNode<int,int>(2);
        NodeStart->pushNewNode(Node1);
        NodeStart->getNode(1)->pushNewNode(Node2);
    
        char value1 = NodeStart->getValue();
        int value2 = NodeStart->getNode(1)->getValue();
        int value3 = NodeStart->getNode(1)->getNode(2)->getValue();
    
    }
    
    template <typename T1, typename T2>
    IDTreeNode<T1,T2>::IDTreeNode(T1 value)
    {
        myValue = value;
    }
    template <typename T1, typename T2>
    bool IDTreeNode<T1,T2>::existNode(T2 value)
    {
        if(myNodes.count(value) > 0) return true;
        return false;
    }
    
    //Funktioniert nicht
    template <typename T1, typename T2>
    void IDTreeNode<T1,T2>::addNode(IDTreeNode *node)
    {
        myNodes[node->getValue()] = node;
    }
    
    //Funktioniert
    /*
    template <typename T1, typename T2>
    void IDTreeNode<T1,T2>::addNode(IDTreeNode<T2,T2> *node)
    {
        myNodes[node->getValue()] = node;
    }
    */
    
    template <typename T1, typename T2>
    T1 IDTreeNode<T1,T2>::getValue()
    {
        return myValue;
    }
    template <typename T1, typename T2>
    IDTreeNode<T2,T2> *IDTreeNode<T1,T2>::getNode(T2 value)
    {
        return myNodes[value];
    }
    

    Frage:
    Ist eigentlich klar 😃 . Wie löse ich das am besten?
    Optimal wäre wohl ein Pointer. Aber gibt es einen, bei dem ich eben nicht den Datentyp angeben muss?
    Ich habe es schon mit auto versucht, da meckert der Compiler auch. Vielleicht habe ich auto auch nur falsch benutzt...
    Ich hatte auch die Idee, ein zweites template-struct zu bauen, das nur den Wert speichert und an den entsprechenden Knoten gehängt wird, aber an sich habe ich da ja wieder das gleiche Problem. Ich muss für eine Referenz den Typ kennen, den ich ja erst zur Laufzeit kenne...

    Ich schreibe den Baum um zu lernen, wie ich mit templates umzugehen habe. Es bringt mir also recht wenig, wenn jemand schreibt "benutz doch diesen Container aus jener lib" 😉 .

    Viele Grüße
    Cherup


Log in to reply