Wie erzwinge ich die Kopierfreiheit, warum funktioniert es nicht mit dem Konstruktor für gelöschte Kopien?

9

Ich habe eine uncodierbare Klasse. Kopieren wäre problematisch. Ich möchte garantieren , dass es nie kopiert wird, also habe ich seinen Kopierkonstruktor deleted :

erstellt %Vor%

Leider wird g ++ dies nicht auf den Grund kompilieren:

%Vor%

Aber dies ist eine sehr klare Situation, in der die Kopier-Elision verwendet werden sollte, so dass der Kopierkonstruktor niemals aufgerufen werden sollte. Warum ist es so?

    
peterh 06.07.2016, 13:08
quelle

3 Antworten

9

Bis C ++ 17 copy elision ist eine Optimierung, die der Compiler nicht ausführen muss. Daher müssen Klassen kopierbar sein, da der Compiler möglicherweise kopieren möchte (auch wenn dies nicht der Fall ist). In C ++ 17 wird in vielen Fällen eine Kopierfreigabe garantiert, und dann brauchen die Klassen keine Kopierzeichen.

Siehe auch:

Ссылка

Ссылка

Ссылка (das Bit über "Garantierte Kopie elision")

Sie könnten vielleicht den alten Trick benutzen, den Kopierkonstruktor in Ihrer Klasse zu deklarieren, aber nicht wirklich zu implementieren? Das sollte dem Compiler gefallen, solange er den copy ctor nicht aufruft. Ich habe das nicht getestet, aber ich glaube, es sollte für Ihren Fall funktionieren, bis C ++ 17 eintrifft.

    
Jesper Juhl 06.07.2016, 13:18
quelle
8

Sie können die Eliminierung der Kopie (noch) nicht erzwingen (siehe andere Antworten).

Sie können jedoch einen Standard-Move-Konstruktor für Ihre Klasse angeben. Dadurch wird der Rückgabewert verschoben (und somit nicht kopiert), wenn RVO / NRVO nicht möglich ist. Um dies zu tun, sollten Sie = default für Ihre Move-Konstruktoren hinzufügen:

%Vor%

Beispiel

    
Sombrero Chicken 06.07.2016 13:10
quelle
7

Die Rückgabewertoptimierung (RVO und NRVO) bedeutet nicht die Anforderung, dass die Typen, die durch kopierbar oder bewegbar sind, fallen gelassen werden. Diese Anforderung gilt unabhängig davon, ob Sie RVO erhalten oder nicht.

Der wahrscheinlichste Grund dafür ist, dass die Kopierfreigabe nicht (derzeit) durchgesetzt wird. Es ist eine Optimierung, die auftreten kann und es wäre nicht sinnvoll, Code zu kompilieren oder nicht, basierend darauf, ob diese Optimierung in einer bestimmten Implementierung angewendet wird.

In C ++ 17 wird RVO unter bestimmten Umständen erzwungen, und die Anforderungen an Kopierbarkeit und Beweglichkeit werden fallengelassen.

    
juanchopanza 06.07.2016 13:10
quelle

Tags und Links