Wie implementiert die Standardbibliothek std :: swap?
Wie ist die swap-Funktion implementiert, die in der STL? Ist es so einfach:
template<typename T> void swap(T& t1, T& t2) {
T tmp(t1);
t1=t2;
t2=tmp;
}
In anderen Beiträgen, reden Sie darüber, spezialisiert diese Funktion für Ihre eigene Klasse. Warum hätte ich dies tun müssen? Warum kann ich nicht die std::swap
Funktion?
InformationsquelleAutor der Frage Maximilian Mordig | 2014-08-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie ist
std::swap
umgesetzt?Ja, die Implementierung wurde in der Frage der klassischen C++03.
Mehr in die moderne (C++11) die Umsetzung der
std::swap
sieht wie folgt aus:Dies ist eine Verbesserung gegenüber der klassischen C++03-Einführung in Bezug auf Ressourcen-management, weil es verhindert, dass nicht benötigte Kopien, etc. Es, die C++11
std::swap
erfordert die ArtT
werden MoveConstructible und MoveAssignableso dass für die Implementierung und den Verbesserungen.Warum brauche ich, um eine benutzerdefinierte Implementierung?
Eine benutzerdefinierte Implementierung von
swap
für einen bestimmten Typ, ist in der Regel empfohlen, wenn Ihre Implementierung effizienter ist, oder spezifischer als die standard-version.Ist ein klassisches Beispiel dafür ist, wenn die Klasse verwaltet eine große Menge an Ressourcen, die sein würde, teuer zu kopieren und dann löschen. Anstatt, Ihre benutzerdefinierte Implementierung könnte tauschen Sie hierzu einfach die handles oder Zeiger benötigt, um die Wirkung vertauschen.
Mit dem Aufkommen der
std::move
und beweglichen Typen (und implementiert Ihre Art als solche), um C++11 und ab, viel von der ursprünglichen Begründung, der hier beginnt zu fallen Weg; aber dennoch, wenn Sie eine benutzerdefinierte swap wäre besser als der standard, es umzusetzen.Generische code wird in der Regel in der Lage sein, um Ihre benutzerdefinierten
swap
wenn es nutzt die ADL Mechanismus entsprechend.InformationsquelleAutor der Antwort Niall
Die Umsetzung? Es ist eine Spezifikation, nicht einen einzigen, konkreten Bibliothek. Wenn du meinst wie kann mein compiler standard-Bibliothek tun esentweder sagen Sie uns, welche compiler ist, oder Lesen den code selbst.
Das ist im wesentlichen die naive version pre-C++11.
Diese un-spezialisierte Umsetzung zwingt zu einer Kopie: für
T = std::vector<SomethingExpensive>
in Ihrem Beispiel, der code übersetzt:so zu tauschen zwei Vektoren, die wir im wesentlichen geschaffen drei. Es wurden drei dynamische Zuweisungen und viele teure Objekte kopiert, und alle diese Vorgänge werfen könnte, möglicherweise verlassen der Argumente in einem unbestimmten Zustand.
Da war natürlich schrecklich, überladungen waren für die teuren Behälter, und Sie wurden ermutigt, zu schreiben überladungen für Ihre eigenen teuren Typen: zB. die
std::vector
Spezialisierung hatte Zugriff auf die vector-Interna, und könnte tauschen Sie zwei Vektoren, ohne alle kopieren:Beachten Sie, dass es sich um keine Kopien überhaupt etwas teuer, keine dynamische (de -) Allokation, und ist garantiert nicht zu werfen.
Nun, der Grund für diese Spezialisierung ist, dass vector::swap hat Zugriff auf vector-Interna, und können sicher und effizient mit Ihnen bewegen, ohne Sie zu kopieren.
Pre-C++11, aus dem gleichen Grund wie
std::vector
zu machen, tauschen effiziente und exception-sicher.Seit C++11, die Sie wirklich nicht -, wenn Sie entweder verschieben, der Bau und der Abtretung oder der compiler generieren kann vernünftige Standards für Sie.
Die neue generische swap:
verwenden können, verschieben Konstruktion/Zuordnung zum erhalten im wesentlichen das gleiche Verhalten wie die custom-Vektor-Implementierung vor, ohne zu schreiben eine benutzerdefinierte Implementierung.
InformationsquelleAutor der Antwort Useless