Chociaż nie mogę znaleźć żadnej wyraźnej wzmianki w tym roboczym projekcie C ++ Standard (od 2014 r.), Że konwersja std::nullptr_t
na typ integralny jest zabroniona, nie ma również wzmianki, że taka konwersja jest dozwolona!
Jednak przypadek konwersji z std::nullptr_t
na bool
jest wyraźnie wymieniony:
4.12 Konwersje boolowskie
Wartość arytmetyczna, nieskalowane wyliczenie, wskaźnik lub wskaźnik na typ elementu można przekształcić na wartość typu bool. Wartość zerowa, wartość wskaźnika zerowego lub wartość wskaźnika pustego elementu są konwertowane na false; każda inna wartość jest konwertowana na true. W przypadku bezpośredniej inicjalizacji (8.5) wartość parametru std :: nullptr_t można przekonwertować na wartość typu bool; wynikowa wartość to false.
Ponadto jedynym miejscem w tym projekcie dokumentu, w którym wymieniono konwersję std::nullptr_t
na typ integralny, jest sekcja „reinterpret_cast”:
5.2.10 Reinterpretacja obsady
...
(4) Wskaźnik można jawnie przekonwertować na dowolny typ integralny wystarczająco duży, aby go pomieścić. Funkcja mapowania jest zdefiniowana w implementacji. [Uwaga: Nie ma w tym nic zaskakującego dla tych, którzy znają strukturę adresowania komputera bazowego. - uwaga końcowa] Wartość typu std :: nullptr_t można przekonwertować na typ całkowy; konwersja ma takie samo znaczenie i ważność jak konwersja (void *) 0 na typ całkowy. [Uwaga: Nie można użyć reinterpret_cast do konwersji wartości dowolnego typu na typ std :: nullptr_t. - uwaga końcowa]
Więc z tymi obserwacjami, można by (IMHO) zasadnie przypuszczać, że MSVC
kompilator jest poprawna.
EDYCJA : Jednak użycie „funkcjonalnej obsady notacji” może faktycznie sugerować coś przeciwnego! MSVC
Kompilator nie ma problemu przy użyciu oddanych C-styl, na przykład:
uintptr_t answer = (uintptr_t)(nullptr);
ale (jak w kodzie) narzeka na to:
uintptr_t answer = uintptr_t(nullptr); // error C2440: '<function-style-cast>': cannot convert from 'nullptr' to 'uintptr_t'
Jednak z tego samego standardu projektu:
5.2.3 Jawna konwersja typu (notacja funkcjonalna)
(1) Specyfikator typu prostego (7.1.6.2) lub specyfikator nazwy typu (14.6), po którym następuje nawiasowana lista wyrażeń konstruuje wartość określonego typu na podstawie listy wyrażeń. Jeśli lista wyrażeń jest pojedynczym wyrażeniem, wyrażenie konwersji typu jest równoważne (w zdefiniowaniu i jeśli zdefiniowano w znaczeniu) z odpowiednim wyrażeniem rzutowanym (5.4). ...
„Odpowiednie wyrażenie rzutowania (5.4)” może odnosić się do rzutowania w stylu C.