co mówi Standard
Standardowe mówi (18,2)
nullptr_t jest zdefiniowany w następujący sposób:
namespace std {
typedef decltype(nullptr) nullptr_t;
}
typu, którego nullptr_t jest synonimem ma cechy opisane w 3.9.1 i 4.10.
Gdzie 3.9.1 mówi zasadniczo powinno być tej samej wielkości co void*
i 4,10 określa zasady konwersji dla nullptr
.
Edit: 3.9.9 ponadto wyraźnie stwierdza, że nullptr_t
jest skalarne typu, co oznacza oczekiwane zasady inicjowania dla wbudowanych typów od 8,5 zastosowanie:
- Default-inicjalizacji (
nullptr_t n;
), który pozostawia nieokreśloną wartość n
. Jak słusznie zauważył Johannes Schaub, kompilacja ta dobrze komponuje się z najnowszą wersją Clanga.
- Wartość inicjalizacji (
nullptr_t n = nullptr_t();
), który inicjuje n 0.
to zachowanie jest identyczna np int
, więc nullptr_t
jest zdecydowanie domyślny-konstruktywny. Interesujące pytanie brzmi: co to oznacza, że dla nullptr_t
ma niezdefiniowaną wartość? Pod koniec dnia jest tylko jedna znacząca możliwa wartość dla nullptr_t
, która jest nullptr
. Ponadto sam typ jest definiowany tylko przez semantykę literału. Czy te semantyki nadal mają zastosowanie do unitialized value?
Dlaczego kwestia ta nie ma znaczenia w praktyce
Nie chcesz zadeklarować nową zmienną typu nullptr_t
. Jedyny znaczący semantyczny tego typu jest już wyrażony poprzez literał, więc zawsze, gdy użyjesz niestandardowej zmiennej typu nullptr_t
, równie dobrze możesz użyć nullptr
.
Co ma znaczenie w praktyce
Jedyny wyjątek to wynika z faktu, że można wziąć non typu parametrów szablonu typu nullptr_t
. W tym przypadku warto wiedzieć, które wartości można przekonwertować na nullptr_t
, co opisano w punkcie 4.10:
null stały wskaźnik stanowi integralną wyrażenie stałe (5,19) prvalue typu liczby całkowitej, która ocenia zero lub prvalue typu std::nullptr_t
. [...] Stała wskaźnika zerowego typu całkowego może zostać przekonwertowana na wartość typu std::nullptr_t
.
które w zasadzie nie tylko to, co można się spodziewać: Można napisać
nullptr_t n = 0; // correct: 0 is special
ale nie
nullptr_t n = 42; // WRONG can't convert int to nullptr_t
Zarówno gcc 4.6 i Clang SVN uzyskać to prawo.
Myślałem, że masz obsłużyć 'nullptr_t' jako zwykły typ wskaźnika, tj. Nie jako klasę. Zakładam, że 'nullptr_t n;' tworzy zmienną _uninitialised_; powinieneś jawnie napisać 'nullptr_t n = nullptr;'. Ale nie mam tu kompilatora C++ 11, więc nie mogę sprawdzić. I nie mogę znaleźć miejsca, w którym to przeczytałem w formalnych specyfikacjach ... –
FWIW, clang akceptuje "nullptr_t n;" tutaj. –