Che cosa dice la standard
La norma dice (18,2)
nullptr_t è definito come segue:
namespace std {
typedef decltype(nullptr) nullptr_t;
}
tipo per il quale nullptr_t è sinonimo ha le caratteristiche descritte nel 3.9.1 e 4.10.
Dove 3.9.1 fondamentalmente dice che dovrebbe essere della stessa dimensione e void*
4.10 specifica le regole di conversione per nullptr
.
Edit: 3.9.9 afferma inoltre esplicitamente che nullptr_t
è un tipo scalare, il che significa che le regole di inizializzazione previsti per tipi built-in da 8.5 applica:
- Default-inizializzazione (
nullptr_t n;
), che lascia il valore di n
indefinito. Come ha indicato correttamente Johannes Schaub, questo si integra bene con la versione più recente di Clang.
- valore di inizializzazione (
nullptr_t n = nullptr_t();
), che inizializza n a 0.
Questo comportamento è identico a es int
, quindi nullptr_t
è decisamente predefinito-constructible. La domanda interessante qui è: cosa significa per nullptr_t
avere un valore non definito? Alla fine della giornata, c'è un solo valore significativo possibile per nullptr_t
, che è nullptr
. Inoltre, il tipo stesso è definito solo attraverso la semantica del valore letterale nullptr
. Queste semantiche si applicano ancora per un valore unitario?
Perché questa domanda non ha importanza nella pratica
Non si vuole dichiarare una nuova variabile di tipo nullptr_t
. L'unica semantica significativa di quel tipo è già espressa attraverso il valore letterale nullptr
, quindi ogni volta che useresti la tua variabile personalizzata di tipo nullptr_t
, puoi anche usare nullptr
.
Ciò che conta, in pratica
L'unica eccezione a questo deriva dal fatto che si può prendere non di tipo parametri di modello di tipo nullptr_t
. In questo caso, è utile sapere quali valori possono essere convertiti in nullptr_t
, che è descritto in 4.10:
Un puntatore nullo costante è un'espressione costante intera (5.19) prvalue di tipo intero che restituisce zero o un prvalue di tipo std::nullptr_t
. [...] Una costante puntatore nullo di tipo integrale può essere convertita in un valore di tipo std::nullptr_t
.
Che sostanzialmente fa proprio quello che ci si aspetta: È possibile scrivere
nullptr_t n = 0; // correct: 0 is special
ma non
nullptr_t n = 42; // WRONG can't convert int to nullptr_t
Sia gcc 4.6 e Clang SVN ottenere questo diritto.
Ho pensato che dovevi gestire un 'nullptr_t' come un semplice tipo di puntatore, cioè non come una classe. Quindi sto assumendo 'nullptr_t n;' crea una variabile _uninitialised_; dovresti scrivere in modo esplicito 'nullptr_t n = nullptr;' Ma non ho un compilatore C++ 11 qui, quindi non posso controllare. E non riesco a trovare dove lo leggo nelle specifiche formali ... –
FWIW, clang accetta "nullptr_t n;" Qui. –