Stimmt es, dass eine unique_ptr-Deklaration im Gegensatz zu einer auto_ptr-Deklaration genau definiert ist, wenn ihr Vorlagentyp unvollständig ist?
Ich hab geschriebenDieser Beitrag und bekam einige Kommentare, die mich verwirrten.
Es läuft im Grunde darauf hinaus, dass ich gesehen habeT2
nur als Template-Parameter verwendet und fälschlicherweise zu dem Schluss gesprungen, dass ich daher die Gelegenheit der Forward-Deklaration nutzen könnte:
struct T2;
struct T1
{
std::auto_ptr<T2> obj;
};
Dies ruft UB auf, wenn ich nicht weiter definiereT2
Irgendwo in der gleichen TU, weilstd::auto_ptr<T2>
Anrufedelete
auf seiner internenT2*
, undBerufungdelete
auf einen Zeiger auf ein Objekt eines unvollständigen Typs, dessen vollständiger Typ einen nicht trivialen Destruktor aufweist, ist nicht definiert:
[C++11: 5.3.5/5]:
Wenn das zu löschende Objekt zum Zeitpunkt des Löschens einen unvollständigen Klassentyp und die gesamte Klasse einen nicht trivialen Destruktor oder eine Freigabefunktion aufweist, ist das Verhalten undefiniert.
Die von mir verwendete GCC-Toolchain - v4.3.3 (Sourcery G ++ Lite 2009q1-203) - war so freundlich, mir Folgendes mitzuteilen:
Hinweis: Weder der Destruktor noch der klassenspezifische Operator delete werden aufgerufen, auch wenn sie beim Definieren der Klasse deklariert werden.
Es scheint jedoch schwierig zu sein, diese Diagnose in anderen GCC-Versionen zu erhalten.
Mein Kritikpunkt war, dass es viel einfacher sein würde, einen Fehler wie diesen zu finden, wenndelete
einen Zeiger auf eine Instanz eines unvollständigen Typsschlecht geformt eher als UB, aber das scheint ein unlösbares Problem für eine Implementierung zu sein, also verstehe ich, warum es UB ist.
Aber dann habe ich das gesagt, wenn ich es benutzen würdestd::unique_ptr<T2>
Stattdessen wäre dies sicher und konform.
n3035 sagt angeblich am 20.9.10.2:
Der VorlagenparameterT
vonunique_ptr
kann ein unvollständiger Typ sein.
Alles, was ich in C ++ 11 finden kann, ist:
[C++11: 20.7.1.1.1]:
/ 1 Die Klassenvorlagedefault_delete
Dient als Standard-Deleter (Vernichtungsrichtlinie) für die Klassenvorlageunique_ptr
.
/ 2 Der VorlagenparameterT
vondefault_delete
kann ein unvollständiger Typ sein.
Aber,default_delete
'soperator()
erfordert einen vollständigen Typ:
[C++11: 20.7.1.1.2/4]:
ObT
ist ein unvollständiger Typ, das Programm ist schlecht geformt.
Ich nehme an, meine Frage lautet:
Sind die Kommentare zu meinem Artikel richtig, wenn sie sagen, dass eine Übersetzungseinheit, die nur aus dem folgenden Code besteht, wohlgeformt und gut definiert ist? Oder liegen sie falsch?
struct T2;
struct T1
{
std::unique_ptr<T2> obj;
};
Wenn sie korrekt sind, wie soll ein Compiler dies implementieren, da es gute Gründe dafür gibt, UB zu sein, zumindest wenn einstd::auto_ptr
wird eingesetzt?