Являются ли итераторы C ++ "безопасными"? - PullRequest
3 голосов
/ 27 января 2011

Я прочитал документацию для итераторов списков C ++, но не мог понять одну вещь: безопасны ли итераторы C ++? Я имею в виду, перестает ли он увеличиваться при достижении последнего существующего элемента в списке?

[] 's

Ответы [ 7 ]

11 голосов
/ 27 января 2011

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

9 голосов
/ 27 января 2011

Вы спрашиваете: выполняет std::list::iterator проверку границ .Ответ - нет, это не так.Это означает, что итератор быстрее, чем в противном случае.Если вам нужна проверка границ, вы можете обернуть итератор своей собственной оберткой для проверки границ.

Но если вы будете следовать соглашениям при использовании итераторов, вы всегда будете знать во время компиляции когда итератор недействителен , т.е. указывает на недопустимую позицию.Например:

  • Когда вы удаляете элемент из std::list, убедитесь, что вы сохранили итератор erase(), чтобы получить действительный итератор, указывающий на новую действительную позицию, сразу за стертым элементом.
  • Когда вы вызываете std::remove(), убедитесь, что вы сохранили возвращенный итератор, чтобы знать, каковы новые границы вашего контейнера.

Этот подход устраняет проблему проверки границ в сторону.при этом сохраняя производительность итераторов, которым не нужно заботиться о том, чтобы пользователь не выстрелил себе в ногу.

3 голосов
/ 27 января 2011

Вы должны проверить, является ли it != list.end(), и выйти из цикла, если достигнут конец.

2 голосов
/ 27 января 2011

Нет. Если вы разыменовываете итератор «из конца в конец», вы получаете неопределенное поведение.

1 голос
/ 27 января 2011

Нет.Как и многие вещи в C ++, по умолчанию используется скорость.

Обоснование заключается в том, что вы можете обменять скорость на безопасность позже, но не наоборот.

0 голосов
/ 10 декабря 2016

Чтобы ответить на ваш вопрос «Нет», они не остановятся, так как ответственность за проверку границ лежит на владельце.

Однако можно поместить проверки в прокси-итератор и применить проверки границ.Это будет стоить вам, хотя, скорее всего, будет цена, чтобы заплатить.Большинство алгоритмов std теперь имеют first / last и для входных, и для выходных итераторов (см. Std :: copy (first_in, last_in, first_out, last_out) и будут проверять границы наряду с теми, которые не принимают конец вывода какне всегда является допустимой операцией (например, конец потока неизвестен до тех пор, пока это не произойдет)

Вы можете написать прокси-сервер итератора, который содержит копию итератора, первую позицию и последнюю позицию. Затем проверьтеесли он выйдет за пределы оператора ++, operator-- и при доступе к членам или разыменованию. Это почти такая же работа, как написание константы каркаса, и его можно использовать как таковой. Для небольшого примера см. Пример итератора-посредника и затем используется Пример использования прокси-сервера итератора

0 голосов
/ 27 января 2011

При правильном использовании итераторы очень полезны.
Поэтому вопрос «Безопасны ли итераторы C ++» будет зависеть от того, как он используется.
Обратите внимание, что неправильное использование printf API может привести к серьезным ошибкам. Реализация будет безопасна для использования или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...