Что говорит Стандарт
Стандарт говорит (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
.
Edit: 3.9.9, кроме того, прямо говорится, что nullptr_t
является скаляром типа, что означает, что ожидаемые правила инициализации для встроенных типов с 8.5 применяются:
- По умолчанию инициализация (
nullptr_t n;
), который оставляет значение n
undefined. Как правильно указал Йоханнес Шауб, это прекрасно компилируется с новейшей версией Clang.
- Значение инициализация (
nullptr_t n = nullptr_t();
), который инициализирует п 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
. [...] Константа нулевого указателя интегрального типа может быть преобразована в prvalue типа 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 получить это право.
Я думал, что вы должны обрабатывать 'nullptr_t' как обычный тип указателя, то есть не как класс. Поэтому я предполагаю, что 'nullptr_t n;' создает переменную _uninitialised_; вы предполагаете, что явно пишите 'nullptr_t n = nullptr;'. Но у меня нет компилятора C++ 11, поэтому я не могу проверить. И я не могу найти, где я прочитал его в формальных спецификациях ... –
FWIW, clang принимает «nullptr_t n;» Вот. –