Что такое единичные и неособые значения в контексте итераторов STL? - PullRequest
10 голосов
/ 26 марта 2011

В разделе § 24.1 / 5 стандарта C ++ (2003) говорится,

Так же, как обычный указатель на массив гарантирует, что есть указатель значение, указывающее за последний элемент массива, поэтому для любого типа итератора есть значение итератора, которое указывает мимо последнего элемента соответствующий контейнер. Эти значения называются ценностями прошлого. Ценности итератора я для которого Выражение * я определен, называются разыменовываемое. Библиотека никогда предполагает, что последние значения разыменовываемое. Итераторы также могут имеют особые значения, которые не являются связан с любым контейнером. [Пример: после объявления неинициализированный указатель x (как с int * x;), x всегда должен иметь единственное значение указателя.] Результаты большинства выражений неопределенный для особых значений; Единственным исключением является присвоение неособое значение для итератора, который имеет единственное значение. В этом случае единственное значение перезаписывается так же, как и любое другое значение. Обоснованные значения всегда неособо.

Я не мог понять текст, показанный жирным шрифтом ?

  • Что такое единственное и неособое значение? Как они определены? А где?
  • Как и почему разыменяемыми значениями являются всегда неособыми?

Ответы [ 4 ]

8 голосов
/ 26 марта 2011

Итераторы также могут иметь единственные значения , которые не связаны ни с одним контейнером .

Полагаю, это его определение.

Как и почему разыменовываемые значения всегда неособы?

Потому что, если они не будут, разыменование их будет неопределенным поведением.

8 голосов
/ 26 марта 2011

Если я правильно понимаю, единственное значение для итератора по существу эквивалентно неназначенному указателю. Это итератор, который не был инициализирован, чтобы указывать куда-либо, и, следовательно, не имеет четко определенного элемента, по которому он повторяется. Например, объявление нового итератора, который не настроен для указания элемента диапазона, создает этот итератор как отдельный итератор.

Поскольку часть спецификации ссылается на то, что итераторы в единственном числе небезопасны, и ни одна из стандартных операций итератора, таких как приращение, присваивание и т. Д., Не может быть использована для них. Все, что вы можете сделать, это присвоить им новое значение, надеясь указать им действительные данные.

Я думаю, что причина этого определения в том, что такие утверждения, как

set<int>::iterator itr;

Может быть разрешено спецификацией, имея стандартизированное значение. Термин «единственное число» здесь, вероятно, относится к математическому определению особенности, которая также называется «разрывом» в менее формальных условиях.

2 голосов
/ 26 марта 2011

Что такое единственное и неособое значение? Как они определены? А где?

Давайте используем простейшее воплощение Iterator: указатель.

Для указателя:

  • единственное значение, на которое ссылаются, является значением NULL неинициализированным значением.
  • неособое значение является явно инициализированным значением, оно не может быть разыменовано до сих пор (указатель конца в конец не должен разыменовываться)

Я бы сказал, что указатель NULL является единственным значением, хотя и не единственным, так как он представляет отсутствие значения.

Какая эквивалентность для регулярных итераторов?

std::vector<int>::iterator it;, конструктор по умолчанию для большинства итераторов (связанных с контейнером) создает единственное значение. Поскольку он не привязан к контейнеру, любая форма навигации (увеличение, уменьшение, ...) не имеет смысла.

Как и почему разыменовываемые значения всегда неособы?

Сингулярные значения, по определению, представляют собой отсутствие действительного значения. Они появляются на многих языках: Python None, C # null, C NULL, C ++ std::nullptr. Загвоздка в том, что в C или C ++ они также могут быть простым мусором ... (что бы там ни было в памяти раньше)

Является ли построенный по умолчанию итератор единственным значением?

Не обязательно, наверное. Стандарт не требуется, и можно представить использование сторожевого объекта.

2 голосов
/ 26 марта 2011

Посмотрите на Каково значение по умолчанию для итератора? .

Как указывает кавычка, единственные значения - это значения итераторов, которые не связаны ни с одним контейнером. Единственное значение почти бесполезно: вы не можете его продвигать, разыменовывать его и т. Д. Один из способов (единственный способ?) Получения единственного итератора - не инициализировать его, как показано в ответе templatetypedef.

Одна из полезных вещей, которые вы можете сделать с единичным итератором, это присвоить это неособое значение. Когда вы делаете это, вы можете делать с ней все, что захотите.

Неингулярные значения, почти по определению, являются значениями итераторов, которые связаны с контейнером. Это объясняет, почему разыменовываемые значения всегда не являются единственными: итераторы, которые не указывают на какой-либо контейнер, не могут быть разыменованы (какой элемент это вернет?).

Как правильно заметил Матье М., неособые значения могут все еще быть разыменованными. В качестве примера можно привести итератор «через конец» (доступный путем вызова container.end ()): он связан с контейнером, но на него нельзя ссылаться.

Я не могу сказать, где эти термины определены. Тем не менее, Google имеет это сказать о «определить: единственное число» (среди других определений):

remarkable: unusual or striking

Полагаю, это может объяснить терминологию.

...