Was die Norm sagt
Der Standard sagt (18,2)
nullptr_t ist wie folgt definiert:
namespace std {
typedef decltype(nullptr) nullptr_t;
}
Die Art, für die nullptr_t ein Synonym ist, hat die beschriebenen Merkmale in 3.9.1 und 4.10.
Wo 3.9.1 im Grunde sagt, dass es die gleiche Größe wie void*
und 4,10 sein sollte, legt die Konvertierungsregeln für nullptr
.
Edit: 3.9.9 ferner ausdrücklich darauf hin, dass nullptr_t
ein Skalar-Typ, der für die erwartete Initialisierung Regeln bedeutet eingebaute Typen von 8,5 gelten:
- Standard-Initialisierung (
nullptr_t n;
), das hinterlässt den Wert n
undefined. Wie Johannes Schaub richtig ausgeführt hat, ist dies mit der neuesten Version von Clang gelungen.
- Wert-Initialisierung (
nullptr_t n = nullptr_t();
), die n auf 0.
Dieses Verhalten ist identisch mit initialisiert z.B. int
, also nullptr_t
ist definitiv standardmäßig konstruierbar. Die interessante Frage hier ist: Was bedeutet es für nullptr_t
, einen undefinierten Wert zu haben? Am Ende des Tages gibt es nur einen sinnvollen möglichen Wert für nullptr_t
, der nullptr
ist. Außerdem ist der Typ selbst nur durch die Semantik des nullptr
Literals definiert. Gilt diese Semantik noch für einen unitären Wert?
Warum diese Frage keine Rolle spielt in der Praxis
Sie wollen nicht nullptr_t
eine neue Variable vom Typ deklarieren. Die einzige sinnvolle Semantik dieses Typs wird bereits durch das nullptr
Literal ausgedrückt. Wenn Sie also Ihre benutzerdefinierte Variable vom Typ nullptr_t
verwenden, können Sie genauso gut nullptr
verwenden.
Was in der Praxis nicht egal
Die einzige Ausnahme davon kommt von der Tatsache, dass Sie nicht-Typ Template-Parameter vom Typ nullptr_t
nehmen. Für diesen Fall ist es nützlich zu wissen, welche Werte in nullptr_t
konvertiert werden können, was in 4 beschrieben ist.10:
Ein Nullzeiger Konstante ist ein integraler konstanter Ausdruck (5.19) prvalue ganzzahliger Typ, der std::nullptr_t
auf Null oder einem prvalue vom Typ auswertet. [...] Eine Null-Zeiger-Konstante vom Integraltyp kann in einen Pr-Wert vom Typ std::nullptr_t
konvertiert werden.
, die im Grunde nur das tut, was man erwarten würde: Sie
nullptr_t n = 0; // correct: 0 is special
schreiben kann, aber nicht
nullptr_t n = 42; // WRONG can't convert int to nullptr_t
Beide gcc 4.6 und Clang SVN dieses Recht bekommen.
Ich dachte, Sie sollten mit einem 'nullptr_t' als einfacher Zeigertyp umgehen, d. H. Nicht als Klasse. Ich nehme an, dass "nullptr_t n;" eine _uninitialized_ Variable erstellt; Sie sollten 'nullptr_t n = nullptr;' explizit schreiben. Aber ich habe hier keinen C++ 11-Compiler, deshalb kann ich das nicht überprüfen. Und ich kann nicht finden, wo ich es in den formalen Spezifikationen lese ... –
FWIW akzeptiert clang "nullptr_t n;" Hier. –