Что говорит Стандарт
Стандарт гласит (18,2)
nullptr_t определяется следующим образом:
namespace std {
typedef decltype(nullptr) nullptr_t;
}
Тип, для которого nullptr_t является синонимом, имеет характеристики, описанные в 3.9.1 и
4,10.
Где 3.9.1 в основном говорит, что он должен быть того же размера, что и void*
, а 4.10 определяет правила преобразования для nullptr
.
Редактировать: 3.9.9, кроме того, прямо указано, что nullptr_t
является скалярным типом, что означает применение ожидаемых правил инициализации для встроенных типов из 8.5:
- Инициализация по умолчанию (
nullptr_t n;
), которая оставляет значение n
неопределенным. Как правильно заметил Йоханнес Шауб, это прекрасно сочетается с новейшей версией Clang.
- Значение-инициализация (
nullptr_t n = nullptr_t();
), которая инициализирует n до 0.
Это поведение идентично, например, int
, таким образом, nullptr_t
определенно является конструируемым по умолчанию.
Интересный вопрос здесь: что означает для nullptr_t
неопределенное значение? В конце дня есть только одно значимое возможное значение для nullptr_t
, которое составляет nullptr
. Кроме того, сам тип определяется только через семантику литерала nullptr
. Применяется ли эта семантика к унитизированному значению?
Почему этот вопрос не имеет значения на практике
Вы не хотите объявлять новую переменную типа nullptr_t
. Единственная значимая семантика этого типа уже выражена через литерал nullptr
, поэтому всякий раз, когда вы будете использовать свою пользовательскую переменную типа nullptr_t
, вы также можете использовать nullptr
.
Что имеет значение на практике
Единственное исключение из этого заключается в том, что вы можете принимать нетипизированные параметры шаблона типа nullptr_t
. Для этого случая полезно знать, какие значения можно преобразовать в nullptr_t
, что описано в 4.10:
Константа нулевого указателя - это целочисленное константное выражение (5.19) prvalue целочисленного типа с нулевым значением или prvalue типа std::nullptr_t
. [...]
Константа нулевого указателя целочисленного типа может быть преобразована в значение типа std::nullptr_t
.
Что в основном делает то, что вы ожидаете: вы можете написать
nullptr_t n = 0; // correct: 0 is special
но не
nullptr_t n = 42; // WRONG can't convert int to nullptr_t
И gcc 4.6, и Clang SVN понимают это правильно.