STL Container und nur Moveable-Types in C++03



  • 1.) Weil shared_ptr kein size-Attribut hat.
    2.) Weil ich kein Ownership teilen moechte.
    3.) Weil ich keine Synchronization moechte.
    4.) Keine Ahnung ob g++ 3.3.5 den in irgendeiner Weise zur Verfuegung stellt.



  • Das Problem ist, dass dein M kopierbar ist. 😉
    Das Konzept eines moveable aber nicht copyable Type lässt sich in C++03 afaik nicht vernünftig ausdrücken. Wenn ich deine M s in einen vector stuff packe und dann z.B. schreib M bla = stuff[123] , dann kompiliert das problemlos, ist aber ganz und gar nicht toll. Möglicherweise kann man mit const was tricksen, z.B. dass man so ein implizites Moven verhindert, indem man die Objekte im vector const macht. Eine wirklich allgemeine und elegante Lösung gibt es aber wohl nicht...



  • Das ist korrekt, d.h. dein Beispiel waere solch ein Defekt. Konkret soll die Klasse M eine Nachricht repraesentieren und in std::priority_queue und std::deque verwendet. Diese haben bereits ein beschraenktes Interface und bieten nur push und pop in verschiedenen Variationen an. Aber der darunterliegende Container ist per default ein std::vector . Das ist das Problem.

    Erzingen std::priority_queue oder std::queue ebenfalls, dass der Typ kopierbar (im Sinne von: a = b => a == b) sein muss?



  • Wieso genau muss M denn moveable sein? Könnte man das entsprechende Konzept nicht vielleicht im Interface des Containers ausdrücken, also z.B. einfach einen entsprechenden Container Adapter bauen und M in Ruhe lassen?

    Afaik ist Kopierbarkeit mehr oder weniger eine Grundanforderung aller Standardcontainer in C++03 (genaugenommen sind die Anforderungen an den Typen afaik für jede Operation extra definiert, aber ohne Kopierbarkeit wird der Container wohl praktisch nutzlos, zumindest std::vector und vermutlich auch deque, bei list, map oder set kann mal unter Umständen ohne davonkommen).

    Edit: Ok, ohne Default Ctor und Copy Assignment könnte man bei list etc. evtl. noch leben, aber ohne Copy Ctor wirds schwer...



  • Edit: -



  • Container Adapter bauen

    Habe ich ja schon, std::priority_queue und std::queue .

    Container wohl praktisch nutzlos

    Nun, ich will die Elemente nur in den Container reinpacken und wieder rausholen. Eine Messagequeue halt. Sie soll nicht kopiert werden.

    Nun fehlt mir leider das Detailwissen. Bei SGIs STL Beschreibung (Wo sonst steht das vernuenftig?) steht beispielsweise Nur Assignable und nur wenn operator== benutzt wird, dann sollte EqualityComparable sein. Wenn ich == im Beispiel von std::queue<M> nicht benutze, kann ich dann auch sicher sein, dass nicht schlimmes passiert, wenn der darunterliegende Container std::vector<M> ist?

    Ziel ist natuerlich, so viel wie moeglich aus der C++ Standardbibliothek nachzunutzen, insbesondere Container (weil Nachrichten als Elemente einfacher selbst zu implementieren sind), und unnoetige Kopieroperationen von Nachrichten zu vermeiden.


  • Mod

    knivil schrieb:

    g++ 3.3.5

    Der ist allerdings schon ziemlich lange EOL.



  • Die Problematik wurde vor allem durch die Speicherung von std::auto_ptr in STL-Containern bekannt. Wenn du danach suchst, findest du genauere Informationen.

    Aber grundsätzlich erfordern STL-Container in C++03 nicht-destruktive Kopierbarkeit. Wenn du diese verletzt, sind Probleme nicht ausgeschlossen. Allerdings wird es schon schwierig, dass der Code überhaupt kompiliert.

    void std::vector<T>::push_back(const T& element)
    {
        T copy(element);
        ...
    }
    
    std::vector<M> vec;
    M obj;              // hat Kopierkonstruktor M::M(M&)
    vec.push_back(obj); // keine Kopie von Const-Referenz möglich
    

    Früher habe ich in diesen Fällen oft Boosts Pointer-Container benutzt. Zur Not tuts auch ein std::vector<T*> .



  • camper schrieb:

    knivil schrieb:

    g++ 3.3.5

    Der ist allerdings schon ziemlich lange EOL.

    Ja, aber leider habe ich keine Wahl. Vielleicht ... mal schauen.

    Die Problematik wurde vor allem durch die Speicherung von std::auto_ptr in STL-Containern bekannt. Wenn du danach suchst, findest du genauere Informationen.

    Ja, das ist mir bekannt, deswegen frage ich ja. Aber alle haben nur ein std::vector als Beispiel.

    Zur Not tuts auch ein std::vector<T*>

    Das wird es wohl werden und ich werde dots Vorschlag folgeleisten.



  • boost.move?


Anmelden zum Antworten