Где я могу найти все гарантии исключения для стандартных контейнеров и алгоритмов?
Да, я просмотрел стандарты С++, которые я мог найти (или черновики), но я не нахожу никаких всеобъемлющие гарантии исключений, предоставляемые контейнерами STL. Все, что я могу найти, это эпизодические разделы с неполными описаниями некоторых функций для некоторых типов. Или, возможно, там, но я просто не нахожу его, я не знаю.
Примечание: Я не запрашиваю список всех гарантий, о которых люди могут подумать, что в основном находится в этот вопрос.
Я ищу авторитетный источник этой информации - или, предпочтительно, бесплатную версию источника (например, проект стандарта), где я могу более или менее рассматривать как официальный.
Ответы
Ответ 1
Чтение стандарта может быть страшным (вернемся к стандарту), но Бьярне Страуступ написал действительно замечательное приложение на эту тему в своей книге "Язык программирования С++". Он разместил это приложение в
http://www.stroustrup.com/3rd_safe0.html, на
http://www.stroustrup.com/3rd_safe.pdf
Это довольно длинный и подробный (и хорошо написанный). Вы можете, например, найти раздел E.4, интересный, цитата:
E.4 Стандартные гарантии контейнера
Если сама библиотечная операция генерирует исключение, она может - и делает - убедитесь, что объекты, на которых он работает, остаются в четко определенное состояние. Например, при() throw out_of_range для вектор (§16.3.3) не является проблемой с безопасностью исключения для вектора, У писателя at() нет проблем, удостоверяясь, что вектор находится в четко определенное состояние перед бросанием.
Кроме того, в разделе E.4.1 указано
В дополнение к основной гарантии стандартная библиотека предлагает сильная гарантия для нескольких операций, которые вставляют или удаляют элементы.
см. стр. 956. Он содержит таблицу гарантий для различных операций для вектора, дека, списка и карты.
Таким образом, все операции над этими контейнерами являются либо недробными, либо сильными, за исключением вставки N-элементов в карту, которая предлагает основные гарантии.
Примечание: приведенный выше текст является старым и не относится к С++ 11, но должен быть достаточно правильным для большинства целей и задач.
Когда дело доходит до С++ 11...
стандартные первые состояния, о контейнерах
array, deque, forward_list, list, vector, map, set, unordered_map, unordered_set, queue,stack
:
при
23.2.1/10:
Если не указано иное (см. 23.2.4.1, 23.2.5.1, 23.3.3.4 и 23.3.6.5) все типы контейнеров, определенные в этом разделе, удовлетворяют следующим дополнительным требованиям:
- если исключение выбрано функцией insert() или emplace(), тогда как вставка одного элемента, эта функция не имеет эффектов.
- если исключение выбрано функцией push_back() или push_front() эта функция не имеет эффектов.
- никакая функция erase(), clear(), pop_back() или pop_front() не выбрасывает исключение.
- никакой конструктор копирования или оператор присваивания возвращенного итератора выбрасывает исключение. - никакая функция swap() не генерирует исключение.
- никакая функция swap() не делает никаких ссылок на ссылки, указатели или итераторы, ссылающиеся на элементы смененных контейнеров.
Приоритеты, указанные в соответствующих разделах, упомянутых выше (каждая из которых называется гарантиями безопасности Exception), в основном касаются специальных случаев против стены, например, при обработке исключений из хэширования содержащихся типов, операций сравнения, а также замены swap и бросать операции перемещения.
Ответ 2
n3376
23.2.1 Общие требования к контейнерам [container.requirements.general]
Пункт 10
Если не указано иное (см. 23.2.4.1, 23.2.5.1, 23.3.3.4 и 23.3.6.5), все типы контейнеров, определенные в этом разделе, удовлетворяют следующим дополнительным требованиям:
- если исключение выбрано функцией insert() или emplace() при вставке одного элемента, эта функция не имеет эффектов.
- если исключение выбрано функцией push_back() или push_front(), эта функция не имеет эффектов.
- никакие функции erase(), clear(), pop_back() или pop_front() не генерируют исключение.
- никакой конструктор копирования или оператор присваивания возвращенного итератора не генерируют исключение.
- никакая функция swap() не генерирует исключение.
- никакая функция swap() недействительна для любых ссылок, указателей или итераторов, ссылающихся на элементы обменяемых контейнеров.
[Примечание: Итератор end() не ссылается ни на какой элемент, поэтому он может быть недействительным. -endnote]
23.2.4 Ассоциативные контейнеры [associative.reqmts]
23.2.4.1 Гарантии безопасности исключений [associative.reqmts.except]
1 Для ассоциативных контейнеров никакая функция clear() не генерирует исключение. erase (k) не генерирует исключение, если только это исключение выбрано контейнерами. Сравните объект (если есть).
2 Для ассоциативных контейнеров, если исключение генерируется какой-либо операцией из функции вставки или emplace, вставляющей один элемент, вставка не влияет.
3 Для ассоциативных контейнеров никакая функция подкачки не генерирует исключение, если это исключение не генерируется заменой контейнеров. Сравните объект (если есть).
23.2.5 Неупорядоченные ассоциативные контейнеры [unord.req]
23.2.5.1 Гарантии безопасности исключений [unord.req.except]
1 Для неупорядоченных ассоциативных контейнеров никакая функция clear() не генерирует исключение. erase (k) не генерирует исключение, если это исключение не выбрасывается контейнерами Hash или Pred object (если таковые имеются).
2 Для неупорядоченных ассоциативных контейнеров, если исключение генерируется любой операцией, отличной от хэш-функции контейнеров, из функции вставки или emplace, вставляющей один элемент, вставка не влияет.
3 Для неупорядоченных ассоциативных контейнеров никакая функция подкачки не генерирует исключение, если это исключение не генерируется обменом контейнеров Hash или Pred object (если таковые имеются).
4 Для неупорядоченных ассоциативных контейнеров, если исключение выбрано из функции rehash(), отличной от хэш-функции контейнера или функции сравнения, функция rehash() не имеет эффекта.
23.3.3.4 модификаторы deque [deque.modifiers]
void push_back (T && x); Пункт 2
Примечания. Если исключение выбрано иначе, чем конструктор копирования, переместите конструктор, оператор присваивания или оператор переадресации перемещения T, никаких эффектов нет. Если исключение вызывается конструктором перемещения не-CopyInsertable T, эффекты не заданы.
стирание итератора (сначала const_iterator, const_iterator); Пункт 6
Throws: Nothing, если конструктор копирования не генерирует исключение, перемещает конструктор, оператор присваивания или оператор назначения перемещения из T.
23.3.6.5 векторные модификаторы [vector.modifier]
void push_back (T && x); Пункт 2
Если исключение вызывается конструктором перемещения не-CopyInsertable T, эффекты не заданы.
стирание итератора (сначала const_iterator, const_iterator); Пункт 5
Throws: Nothing, если конструктор копирования не генерирует исключение, перемещает конструктор, оператор присваивания или оператор назначения перемещения из T.
Ответ 3
Документ, с которым вы связались, проект стандарта n3337, может рассматриваться как официальный. Это стандарт С++ 11 плюс незначительные редакционные изменения.
Вам просто нужно научиться читать стандарт, что понятно, потому что оно не предназначено для легкого чтения.
Чтобы найти гарантии исключения для какой-либо конкретной операции с библиотекой, проверьте эту спецификацию операции для замечаний и комментариев об исключениях. Если функция является функцией-членом, то проверяйте спецификацию типа комментариев для безопасности исключений и какие требования он выполняет. Затем проверьте выполняемые требования для гарантий исключения, которые должны выполняться объектами для выполнения этих требований.
Для генерических типов и алгоритмов также проверяйте требования, предъявляемые к параметрам шаблона, чтобы узнать, какие требования должны соответствовать этим типам для всех гарантий исключения, выполняемых типом или алгоритмом или функцией-членом (если шаблон параметры не соответствуют указанным требованиям, тогда использование шаблона с этими параметрами имеет поведение undefined, и ни одна из спецификаций шаблона не применяется).