Мне любопытно узнать, как работает nullptr.
Он работает самым простым способом: fiat . Это работает, потому что стандарт C ++ говорит, что работает, и работает так, как работает, потому что стандарт C ++ говорит, что реализации должны заставить его работать таким образом.
Важно признать, что невозможно реализовать std::nullptr_t
с использованием правил языка C ++. Преобразование из константы нулевого указателя типа std::nullptr_t
в указатель не является определяемым пользователем преобразованием. Это означает, что вы можете go из константы нулевого указателя в указатель, а затем с помощью пользовательского преобразования в какой-либо другой тип, все в одной неявной последовательности преобразования.
Это невозможно, если вы реализуете nullptr_t
как класс. Операторы преобразования представляют пользовательские преобразования, а правила неявной последовательности преобразования C ++ не допускают более одного пользовательского преобразования в такой последовательности.
Таким образом, опубликованный вами код является хорошим приближением std::nullptr_t
, но это не более того. Это не законная реализация типа. Вероятно, это было из более старой версии компилятора (оставленной в целях обратной совместимости) до того, как компилятор обеспечил надлежащую поддержку std::nullptr_t
. Это можно увидеть по тому факту, что он #define
s nullptr
, в то время как C ++ 11 говорит, что nullptr
является ключевым словом , а не макросом.
C ++ не может реализовать std::nullptr_t
, так же как C ++ не может реализовать int
или void*
. Только реализация может реализовать эти вещи. Это то, что делает его «фундаментальным типом»; это часть языка .
, его значение может быть преобразовано в целочисленный тип идентично (void *) 0, но не в обратном направлении;
нет неявного преобразования из константы нулевого указателя в целочисленные типы. Существует преобразование из 0
в целочисленный тип, но это потому, что это целочисленный литеральный ноль, который является ... целым числом.
nullptr_t
может быть приведением к целочисленный тип (через reinterpret_cast
), но он может быть неявно преобразован только в указатели и в bool
.