Могут ли методы итератора STL вызвать исключение - PullRequest
18 голосов
/ 26 октября 2011

Деструкторы не могут выдавать исключения (поэтому разматывание стека может завершиться во время обработки исключений) и должны освобождать любые ресурсы, выделенные объекту (поэтому утечка ресурсов отсутствует). Проект для объекта, который содержит несколько других объектов (или выделено несколько ресурсов), может записывать указатели на них в контейнере STL. Поэтому деструктор будет использовать следующие методы, связанные с итераторами:

  • begin(), end() для контейнера
  • operator++ для действительного итератора
  • operator* или operator-> для действительного итератора

Но чтобы гарантировать, что деструктор не генерирует исключения и освобождает свои ресурсы, вам нужно полагаться на эти методы, никогда не генерирующие исключения.

Безопасно ли полагаться на эти методы, никогда не создавая исключения? Трудно представить практическую реализацию, которая бы генерировала исключения, так как итератор STL по сути является указателем. Но требует ли стандарт C ++ , чтобы эти методы никогда не генерировали исключения? Я не нашел четкого утверждения в стандарте C ++.


Редактировать : Интересный случай для C ++ 03, когда вы хотите иметь контейнер указателей на ресурсы . Есть веские причины для этого; например, если у вас есть полиморфные ресурсы. Как указывает Björn Pollex в своем ответе, если вы используете контейнер ресурсов (например, std::list< Resource >), а не контейнер указателей на ресурсы, деструктор контейнера позаботится об уничтожении ( освобождение) Resource объектов для вас.

Ответы [ 4 ]

16 голосов
/ 26 октября 2011

оператор ++ для действительного итератора

Стандарт C ++ (я имею в виду черновик N3290) не дает гарантии nothrow для оператора приращения итераторов.

Например,std::istreambuf_iterator::operator++ эффектов при вызове std::basic_streambuf::sbumpc.sbumpc может вызвать uflow, что, в свою очередь, может вызвать исключение.

6 голосов
/ 26 октября 2011

без конструктора копирования или оператора присваивания возвращаемого итератора выдает исключение

Это из стандарта C ++ 03. Я не думаю, что стандарт идет дальше этого.

Btw. это 23.1.10

1 голос
/ 26 октября 2011

Поэтому деструктор будет использовать следующий связанный с итератором Методы

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

Если вы правильно используете RAII, вы почти никогда не столкнетесь со сценарием, когда вам придется явно освобождать ресурсы. Это может быть достигнуто с помощью хранилища контейнеров shared_ptr или unique_ptr или с помощью чего-то вроде Boost.Pointer Container .

0 голосов
/ 23 декабря 2013

Согласно http://www.tenouk.com/Module31.html эти операции (для '*' и '->' это зависит также от хранимого типа) не являются выбросами для контейнеров STL.

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