Der folgende Code verhält sich mit oder ohne benutzerdefinierten Kopierkonstruktor anders unter GCC 8.0.1:
#include <cassert>
struct S {
int i;
int *p;
S() : i(0), p(&i) {}
// S(const S &s) : i(s.i), p(&i) {} // #1
// S(const S &s) : i(s.i), p(s.p) {} // #2
// S(const S &s) = delete; // #3
};
S make_S() {return S{};}
int main()
{
S s = make_S();
assert(s.p == &s.i);
}
Mit jedem der kommentierten benutzerdefinierten Kopierkonstruktoren (selbst mit Nr. 2, demjenigen, der eine einfache flache Kopie durchführt) schlägt die Assertion nicht fehl, was bedeutet, dass das garantierte Entfernen der Kopie wie erwartet funktioniert.
Ohne einen benutzerdefinierten Kopierkonstruktor schlägt die Assertion jedoch fehl, was das Objekt bedeutet s
in main
Die Funktion ist nicht standardmäßig konstruiert. Warum passiert das? Funktioniert die garantierte Kopierelision hier nicht?
Guaranteed copy elision und RVO sind jedoch nicht ein und dasselbe
– StoryTeller – Unslander Monica
20. Februar 18 um 6:38 Uhr
Erwähnenswert ist auch, dass es auch auf Clang 7.0.0 fehlschlägt
– StoryTeller – Unslander Monica
20. Februar 18 um 6:42 Uhr
@StoryTeller RVO erfüllt in diesem Beispiel die Kriterien der garantierten Entfernung von Kopien. Es ist eine Initialisierung von einem Prvalue desselben Klassentyps.
– xskxzr
20. Februar 18 um 6:51 Uhr
@juanchopanza Es scheint, dass GCC die garantierte Entfernung von Kopien seit Version 7 vollständig unterstützt dieser Tisch
– xskxzr
20. Februar 18 um 6:57 Uhr
Ich irre mich wahrscheinlich, aber ich kann wirklich nichts Falsches an Ihrem Beispiel finden, das die Kopierentfernung fehlerhaft machen würde. Ich vermute ein QOI-Problem (sowohl für Clang als auch für GCC).
– StoryTeller – Unslander Monica
20. Februar 18 um 7:10 Uhr