Copy And Swap Implementation ok?



  • @Quiche-Lorraine sagte in Copy And Swap Implementation ok?:

    Ich bräuchte im Endeffekt einen String welche wir std::string funktioniert aber standardmäßig solange keinen Speicher allokiert bis ihm etwas zugewiesen wird.

    Ich kenne keine std::string Implementierung die (in Release Builds) für einen leeren String dynamisch Speicher anfordert. Was du siehst könnte das Iterator-Debugging von der Visual Studio Standard Library sein. Das führt IIRC in Debug Builds dazu dass für jeden Container oder String eine dynamische Speicheranforderung nötig ist. Der erzeugt da dynamisch irgend ein kleines Objekt das er zum Tracking der Iteratoren benötigt.

    Wenn du Iterator-Debugging auch in Debug Builds deaktivieren willst, kannst du einfach in deinen Projekteinstellungen das Präprozessormakro _ITERATOR_DEBUG_LEVEL auf 0 definieren.

    Was allerdings weiterhin bleibt ist dass ein std::string grösser ist als eine spezialisierte Klasse die nur einen einzigen Zeiger enthält. Nämlich grob 4 mal so gross (leicht unterschiedlich je nach Implementierung). Also z.B. 32 Byte statt 8 Byte. Bei 1 Million Strings wären das von der Grössenordnung her 20-30 MB, was auf modernen Systemen vermutlich wörscht ist. Dafür ist für sehr kurze Strings (z.B. 6 oder 8 Zeichen) typischerweise gar keine dynamische Speicheranforderung nötig.



  • @Schlangenmensch sagte in Copy And Swap Implementation ok?:

    Ich persönlich bin einfach kein Freund davon, selbst etwas in namespace std{} zu schreiben und rechne auch nicht damit, dass jemand anderes das machen würde.

    Bei std::swap ist das eigentlich recht üblich soweit ich weiss und war vom Standard bis inklusive C++17 explizit erlaubt. Wurde bei C++20 anscheinend geändert, keine Ahnung warum 😞

    Bei Standard-Library Klassen ist es weiterhin explizit erlaubt. Und bei Dingen wie std::hash kommst du auch gar nicht drumrum.



  • @hustbaer
    Danke, mit _ITERATOR_DEBUG_LEVEL 0 funktioniert es auch mit einem std::string!



  • @Schlangenmensch sagte in Copy And Swap Implementation ok?:

    1. Define a friend function in-class (this approach hides the class-specific swap from name lookup other than ADL)

    das geht doch so ohne friend, oder?

    class X
    {
       void swap(X &rhs)
      {
         ...
      }
    };
    
    swap(X &lhs, X &rhs)
    {
       lhs.swap(rhs);
    }
    

    wenn die Klasse und die Funktion im gleichen Namensraum definiert sind ... ?



  • @Belli
    Gehen tut es schon. Nur trifft dann das was in Klammern steht ("this approach hides the class-specific swap from name lookup other than ADL") nicht mehr zu.
    Weiss aber nicht ob das jetzt besonders wichtig ist.



  • Mhm, ich verstehe das gar nicht recht: Ich will doch meinen swap gar nicht verstecken?!



  • Naja die Frage ist ob es ohne ADL sichtbar/findbar sein muss.
    Und mir fällt grad kein guter Grund dafür ein.
    Allerdings fällt mir auch kein guter Grund ein es zu verstecken. Falls jmd. einen kennt, lasst es mich gerne wissen 🙂



  • @Th69 sagte in Copy And Swap Implementation ok?:

    @john-0: Da fehlt wohl eine Leerzeile nach dem Zitat (denn der letzte Satz ist doch wohl von dir?).

    Ja, ich habe das korrigiert.



  • @Belli hm, ja. Das sollte auch gehen. Aber dann musst du 2 swap Funktionen schreiben, einmal die Member Funkion und dann die freie Funktion außerhalb.



  • Wenn man es mit friend machen will und gleichzeitig will dass swap ohne ADL sichtbar ist, dann muss man swap bloss ausserhalb der Klasse definieren. Oder innerhalb der Klasse und definieren und ausserhalb nochmal ne declaration schreiben. Geht auch.

    Beispiel:

    #include <utility>
    
    namespace Version1 {
        class Foo {
            int i;
            friend void swap(Foo& x, Foo& y);
        };
    
        // normal definition, visible without ADL
        void swap(Foo& x, Foo& y) {
            using std::swap;
            swap(x.i, y.i);
        }
    }
    
    namespace Version2 {
        class Bar {
            int i;
            friend void swap(Bar& x, Bar& y) {
                using std::swap;
                swap(x.i, y.i);
            }
        };
    
        void swap(Bar& x, Bar& y); // declaration: also makes it visible without ADL
    }
    
    void fun() {
        auto s1 = &Version1::swap; // without ADL: works
        auto s2 = &Version2::swap; // without ADL: works
    }
    




  • @Swordfish
    Guter Fund!


Anmelden zum Antworten