Namen für typedefs



  • Hallo zusammen,

    jedesmal wenn ich ein typedef festlege bin ich am grübeln, nach welchem Schema ich die Namen vergeben soll.

    Zum Beispiel:

    struct DataPoint{...};
    struct Station{...};
    
    typedef std::vector<DataPoint>  DataPointVector;
    typedef std::vector<DataPoint*> DataPointPtrVector;
    typedef std::map<int, Station>  StationMap;
    typedef std::map<int, DataPointPtrVector> StationsDataPointMap;
    

    Ich schreibe in den Typnamen also immer den Containertyp mir rein (Verctor, Map, etc.). Nur ist der Sinn eines typedefs auch, dass man relativ einfach den Conteinertyp wechseln kann. Wenn z.B. DataPointVector nun eine Liste werden soll, so muss ich nicht nur den typedef ändern, sondern auch den Namen und somit muss ich auch die Klassendeklaration ändern.

    Somit überlege ich dann folgende Namen zu verwenden:

    typedef std::vector<DataPoint>  DataPoints;       // OK
    typedef std::vector<DataPoint*> DataPointPtrs;    // hier wird mir schon mulmig
    typedef std::map<int, Station>  Stations;         // was ist, wennn ich zusätzlich
                                                      // noch ein std::vector<Station> benötige?
    typedef std::map<int, DataPointPtrs> StationsDataPoints; // Ich weiß nicht...
    

    Irgendwie gehört der Typ für mich schon in den Namen rein, da ja jeder Containertyp eine andere Verwendung ermöglicht/voraussetzt. Container kann man ja nur begrenzt einfach auswechseln. Nur dann ist der Vorteil eines typedefs stark eingeschränkt.

    Was denkt Ihr?



  • DataPointContainer
    StationMap



  • Huch, wo ist denn die Antwort von 314159265358979__ hin?



  • Roger Wilco schrieb:

    Huch, wo ist denn die Antwort von 314159265358979__ hin?

    Die werden jetzt auf Verdacht gelöscht, wenn nicht auf den ersten Blick klar scheint, daß sie nutzbringend sind.



  • cooky451 schrieb:

    DataPointContainer
    StationMap

    Und die anderen typedefs sollte man weglassen?

    @314159265358979__: Keine typedefs für Container mit Zeigern?



  • Roger Wilco schrieb:

    typedef std::vector<DataPoint>  DataPoints;       // OK
    typedef std::vector<DataPoint*> DataPointPtrs;    // hier wird mir schon mulmig
    typedef std::map<int, Station>  Stations;         // was ist, wennn ich zusätzlich
                                                      // noch ein std::vector<Station> benötige?
    typedef std::map<int, DataPointPtrs> StationsDataPoints; // Ich weiß nicht...
    

    Über die Objektnamen würde ich sinnieren. Aber typedeffen von Containern, da bin ich am Zweifeln. Wozu? Zur Not kommt man mit decltype oder Template-Tricks oder auto (insbesondere mit den neuen for-Schleifen) gut genug dran.

    std::vector<DataPoint>  DataPoints;
    std::vector<DataPoint*> DataPoints;
    std::map<int, Station>  IdToStation;
    std::map<int, DataPointPtrs> IdToDataPoint;
    


  • volkard schrieb:

    Typen würde ich gar nicht reinschreiben. Auch nicht, ob die Objekte selber oder nur Zeiger drin sind.

    typedef std::vector<DataPoint>  DataPoints;
    typedef std::vector<DataPoint*> DataPoints;
    typedef std::map<int, Station>  IdToStation;
    typedef std::map<int, DataPointPtrs> IdToDataPoint;
    

    OK, das denke ich auch, aber in dem Beispiel oben, benötige ich alle vier typedefs gelichzeitig.

    typedef std::vector<DataPoint>  DataPoints;    // Datenpunkte
    typedef std::vector<DataPoint*> DataPointPtrs; // Zeiger auf Datenpunkte in (1)
    typedef std::map<int, Station>  IdToStation;   // Stationen mit Stations-ID
    typedef std::map<int, DataPointPtrs> IdToDataPoints; // Zuordnung Datenpunkte zu Station --> std::map<int, std::vector<DataPoint*>>
    

    Wobei ich diese Beispiel wohl über die Indexe des Datenpunkt-Vectors als über Objektzeiger realisieren sollte:

    typedef std::vector<DataPoint>  DataPoints;
    typedef std::vector<size_t>     DataPointIds; // beinhaltet Indexe von DataPoints
    typedef std::map<int, Station>  IdToStation;
    typedef std::map<int, DataPointsIds> StationToDataPointIds; // Datenpunkte der Stationen
    


  • Roger Wilco schrieb:

    Wobei ich diese Beispiel wohl über die Indexe des Datenpunkt-Vectors als über Objektzeiger realisieren sollte:

    Wenn ich dich richtig verstehe sind in deinem Fall die Zeiger ohnehin sehr gefährlich, da die Speicherbereiche von vectoren bei einer Größenänderung umkopiert werden (Das ist der gleiche grund warum Iteratoren ungültig werden können). Wobei ich auch bei den Indexen vorsichtig wäre, wenn nicht sichergestellt ist, das du immer nur hinten einfügst.



  • volkard schrieb:

    Über die Objektnamen würde ich sinnieren. Aber typedeffen von Containern, da bin ich am Zweifeln.

    Oh, du hast Dein Beitrag editiert. Also würdest Du auch sagen, dass man Container eher nicht typedeffen sollte, richtig? Gut, habe ich auch überlegt.

    volkard schrieb:

    Wozu?

    Schreibarbeit? Lesbarkeit? Container lässt sich einfacher austauschen?

    class Foo
    {
        ...
        DataPoints GetDataPoints(...);
    };
    

    volkard schrieb:

    Zur Not kommt man mit decltype oder Template-Tricks oder auto (insbesondere mit den neuen for-Schleifen) gut genug dran.

    Oh, das sagt mir so auf Anhieb nichts. 😕



  • asc schrieb:

    Wenn ich dich richtig verstehe sind in deinem Fall die Zeiger ohnehin sehr gefährlich, da die Speicherbereiche von vectoren bei einer Größenänderung umkopiert werden (Das ist der gleiche grund warum Iteratoren ungültig werden können). Wobei ich auch bei den Indexen vorsichtig wäre, wenn nicht sichergestellt ist, das du immer nur hinten einfügst.

    Ok, ich wollte eigentlich nicht so explizit auf mein aktuelles Beispiel eingehen, sondern allgemein das Thema typedefs klären. Aber das ist mir halt auch gerade aufgefallen, dass ich hier lieber über den Index auf die Datenpunkte verweisen/zugreifen sollte. In diesem Beispiel verwende ich den std::vector<DataPoint> für das "Speichermanagement". Der vector wird einmalig gefüllt und bleibt dann konstant.



  • Roger Wilco schrieb:

    volkard schrieb:

    Wozu?

    Schreibarbeit? Lesbarkeit? Container lässt sich einfacher austauschen?

    Schreibarbeit?

    Man schreibt ja nicht mehr

    for(std::vector<DataPoint*>::iterator i=DataPointPtrs.begin(),e=DataPointPtrs.end();i!=e;++i)
    

    sondern

    for(auto i:DataPointPtrs)
    

    Das nachträgliche Austauschen halte ich für überbewertet. Also mir passiert es recht selten. Zu selten, um mich explizit darum zu kümmern.

    Roger Wilco schrieb:

    class Foo
    {
        ...
        DataPoints GetDataPoints(...);
    };
    

    Naja, klar spart es hier Tipparbeit, die haste aber woanders hinverlagert.

    Roger Wilco schrieb:

    volkard schrieb:

    Zur Not kommt man mit decltype oder Template-Tricks oder auto (insbesondere mit den neuen for-Schleifen) gut genug dran.

    Oh, das sagt mir so auf Anhieb nichts. 😕

    Mit decltype kannste grob gesagt Typen wieder besorgen aus Objekten.

    for(decltype(DataPointPtrs)::iterator i=DataPointPtrs.begin(),e=DataPointPtrs.end();i!=e;++i)
    


  • Ich sehe gerade, dass das Neuerungen in C++11 sind. Ich habe hier leider nur TR1 (VS2008) zur Verfügung.

    Also: Keine typdefs für Container? Ist das der Regelfall in der (prof.) C++-Programmierung?



  • Roger Wilco schrieb:

    Also: Keine typdefs für Container? Ist das der Regelfall in der (prof.) C++-Programmierung?

    So halte ich es. Aber ich hab's auch nicht selten professionell mit Typedefs gesehen. Das ist ja nur eine leichte Umschreibung, die nichtmal im entstehenden Compilat die kleinste Auswirkung hat.

    Roger Wilco schrieb:

    Ich sehe gerade, dass das Neuerungen in C++11 sind. Ich habe hier leider nur TR1 (VS2008) zur Verfügung.

    Der hat stattdessen typeof (oder war's __typeof?). Das kann einem manchmal aus der Patsche helfen.
    edit: Nee, anscheinend hat er's nicht, sondern man kann es sich aus boost holen. Schade.



  • for(decltype(DataPointPtrs)::iterator i=DataPointPtrs.begin(),e=DataPointPtrs.end();i!=e;++i)
    

    😕 Warum nicht einfach

    for(DataPointPtrs::iterator i=DataPointPtrs.begin(),e=DataPointPtrs.end();i!=e;++i)
    

    ????



  • pyhax schrieb:

    for(decltype(DataPointPtrs)::iterator i=DataPointPtrs.begin(),e=DataPointPtrs.end();i!=e;++i)
    

    😕 Warum nicht einfach

    for(DataPointPtrs::iterator i=DataPointPtrs.begin(),e=DataPointPtrs.end();i!=e;++i)
    

    ????

    Weil DataPointPtrs hier ne Variable ist und kein Typ.
    Genau darum gehts ja u.A. in dieser Frage: wenn man dem genauen Typ einen Alias-Namen verpasst (typedef eben), dann kann man

    for(AliasName::iterator i=DataPointPtrs.begin(),e=DataPointPtrs.end();i!=e;++i)
    

    schreiben.
    Wenn man es nicht macht muss man

    for(Namespace::ContainerTyp<ElementTyp, Nochwas, Blubb>::iterator i=DataPointPtrs.begin(),e=DataPointPtrs.end();i!=e;++i)
    

    schreiben, was oft mal etwas länger werden kann. Und lästig ist, wenn man den Container-Typ ändert.

    @Roger Wilco
    Ich persönlich verwende kaum typedefs.
    Vor allem deswegen, weil es mMn. die Einarbeitungszeit erhöht einen Haufen "unnötiger" Namen einzuführen. (Ist ein "Additional Level of Indirection" den man durchwandern muss um an die gewünschte Information zu kommen - nämlich "was ist das für ein Typ?")

    Ich kenne aber auch (professionelle) Projekte wo das genau andersrum gehalten wird, wo für alles gleich ein Typedef gemacht wird. Wenn's da Foo gibt gibt's auch ein typedef shared_ptr<Foo> FooPtr und ggf. gleich noch ein paar weitere ( FooVector , FooPtrVector - was auch immer).



  • Normalerweise kapselt man die Datenstrukturen wie vector und map in einer eigenen Klasse und bietet nur die Operationen nach aussen hin die wirklich gebraucht werden



  • hustbaer schrieb:

    Ich kenne aber auch (professionelle) Projekte wo das genau andersrum gehalten wird, wo für alles gleich ein Typedef gemacht wird. Wenn's da Foo gibt gibt's auch ein typedef shared_ptr<Foo> FooPtr und ggf. gleich noch ein paar weitere ( FooVector , FooPtrVector - was auch immer).

    Darauf (viele typedefs) hatte ich mich auch eingeschossen. Ich denke, ich werde das jetzt auch auf ein Minimum reduzieren.

    Ich danke Euch für Meinungen!


Anmelden zum Antworten