Я обнаружил, что ответ на этот вопрос - неожиданный угол C ++ чернового стандарта , раздел 24.2
Требования к итераторам , в частности раздел 24.2.1
В общем абзац 5 и 10 , в которых соответственно сказано ( выделено мое ):
[...] [Пример: после объявления неинициализированного указателя x (как в случае int * x;), x всегда должно иметь сингулярное значение указателя . - конец примера] [...] Разыменовываемые значения всегда не единственные.
и
Недопустимый итератор - это итератор, который может быть единственным. 268
и сноска 268
гласит:
Это определение относится к указателям, , поскольку указатели являются итераторами . Эффект разыменования итератора, который был признан недействительным, не определен.
Хотя это выглядит так, как будто есть * некоторые противоречия по поводу , является ли нулевой указатель единичным или нет , и похоже, что термин единственное значение должен быть правильно определен в более общем образом.
Намерение единственного числа , кажется, хорошо суммировано в отчете о дефектах 278. Что означает валидность итератора? в разделе с обоснованием:
Почему мы говорим «может быть в единственном числе» вместо «в единственном числе»? Это потому, что действительный итератор - это тот, который известен как невырожденный . Признать недействительным итератор означает изменить его таким образом, чтобы он больше не считался неособым. Пример: вставка элемента в середину вектора, как говорят, делает недействительными все итераторы, указывающие на вектор. Это не обязательно означает, что все они становятся единичными .
Итак делает недействительным и будучи неинициализированным may
создает значение, которое единственное , но поскольку мы не можем доказать, что они неособое мы должны предположить, что они единственного числа .
Обновление
Альтернативным подходом здравого смысла было бы отметить, что проект стандарта раздела 5.3.1
Унарные операторы параграф 1 , который гласит ( выделение шахты ):
Унарный * оператор выполняет косвенное обращение: выражение, к которому он применяется, должно быть указателем на тип объекта или указателем на тип функции, а результатом является lvalue, ссылающееся на объект или функция, на которую указывает выражение. [...]
и если мы перейдем к разделу 3.10
L-значения и r-значения абзац 1 говорит ( выделение мое ):
lvalue (так называемое исторически, потому что lvalue может появляться в левой части выражения присваивания) обозначает функцию или объект. [...]
, но ptr
не будет, за исключением случая, указывать на действительный объект .