2016-03-25 13 views
3

Hintergrund:Kopieren std :: vector von primitiven Typen Verhalten

Wenn ein std::vector Kopieren seiner Kopie Konstruktor oder kopieren Zuordnung wie folgt aus:

std::vector<T> v1{T(),T(),T()}; 
std::vector<T> v2 = v1; 

eine tiefe Kopie geschieht.

Wird durch den Standard garantiert, dass der Kopierkonstruktor von T für jedes Element ausgelöst wird? Mit anderen Worten wird kein memcpy (oder etwas ähnliches) aufgerufen. (Korrigiere mich, wenn ich falsch liege).

Frage:

Auf der anderen Seite wird durch den Standard garantiert, dass es memcpy (oder so ähnlich) auf primitive Typen nennen würde (für Performance-Probleme)?

+0

"Wird durch den Standard garantiert, dass der Kopierkonstruktor des T für jedes Element ausgelöst wird?" - bestimmt. Wie sonst kann es sich verhalten? Warum fragst du überhaupt? – Mikhail

+0

Es wäre verrückt, den Kopierkonstruktor nicht aufzurufen ... – marom

+0

siehe bitte bearbeiten –

Antwort

3

Ja, T 's Copy-Konstruktor muss aufgerufen werden. Wenn der Kopierkonstruktor trivial ist, ist sein Effekt genau derselbe wie der von memcpy, so dass eine Implementierung in Ordnung ist, um den letzteren zu Implementieren diesen Kopierkonstruktor zu verwenden. Von diesem Zeitpunkt an kann die Implementierung entscheiden, memcpy zu verwenden, um den Kopierkonstruktor vector zu implementieren. Diese Entscheidung nutzt die as-if rule: Das beobachtbare Verhalten des Programms bleibt unverändert, daher müssen wir nicht alle Aufrufe des Kopierkonstruktors ausführen.

Auf der anderen Seite, ist es von der Norm, dass es würde Anruf memcpy (oder so ähnlich) auf primitive Typen (für Performance-Probleme) gewährleistet?

Nein, denn wie ein Kopierkonstruktor implementiert wird, ist ein Implementierungsdetail. Der Standard spezifiziert lediglich das (beobachtbare) Verhalten eines Programms, und zwar unter Verwendung des Begriffs der Kopierkonstruktoren usw. Optimierung ist nichts, worüber sich ein abstraktes Standarddokument Sorgen machen sollte, sondern Ihr Lieferant. In der Tat würde die Einschränkung der Definitionen solcher Funktionen entweder ein großes Optimierungsdefizit zur Folge haben oder aufgrund der oben erwähnten "as-if" -Regel völlig ignoriert werden.

2

Der genaue Code, der für die Kopierkonstruktion primitiver Typen generiert wird, ist ein Qualitätsproblem bei der Implementierung. Mit anderen Worten, der Standard garantiert nicht alles von der Art - im besten Fall wird es die algorithmische Komplexität der Operation angeben, in diesem Fall kann das Kopieren des Vektors als O(n) abgeleitet werden.

Mit modernen C++ - Compiler auf eine sinnvolle Optimierung Einstellung können Sie auf Kopie Konstruktion von POD-Klassen in-line, so effizient wie eine konstante Größe memcpy zählen. Alles andere würde mit typischen Anwendungsfällen, wie z. B. STL-Container mit Zeigern, zu ernsthaften Strafen führen.