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
auf0
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 warumBei 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?:
- 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 dassswap
ohne ADL sichtbar ist, dann muss manswap
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 }
-
Das Ganze zusammengefasst: https://stackoverflow.com/a/5695855/10735411
-
@Swordfish
Guter Fund!