Ответ 1
Это сложный вопрос и поднимает некоторые ключевые проблемы, рассмотренные в noexcept - зачем? из Andrzej С++ blog, в котором говорится, что я попытаюсь привести здесь минимум (основное внимание):
В этом сообщении я хотел бы поделиться своим наблюдением, где использование noexcept действительно добавляет ценность. Это реже, чем то, что можно было бы ожидать, и у него не так много общего с бросанием или отсутствием исключений. Заключение меня немного удивляет, и я не решаюсь представить его, потому что это противоречит совету, который я слышу от людей, которых я считаю авторитетами по этому вопросу.
и
Учитывая это негативное отношение к noexcept, его можно считать полезным вообще? Да. Функция noexcept была введена очень поздно в С++ 11 для решения одной конкретной проблемы с семантикой перемещения. Это описано здесь Дугласом Грегором и Дэвидом Абрахамом.
а затем он продолжает задавать необычное определение назначения движения и утверждает, что то, что мы действительно хотим передать, заключается не в том, что оно не генерирует исключений, а в том, что это не подводит, но это очень трудная проблема, но это не реально цель:
[...] Это потому, что информация, которую noexcept действительно предназначена для что функция никогда не терпит неудачу; не то, что он никогда не бросает! Мы может видеть выше, что функция может терпеть неудачу, но все же не бросать, но она по-прежнему квалифицируется как noexcept (false). Возможно, ключевое слово должно иметь был назван nofail. Гарантия никогда не может быть проверена компилятор (как и любая другая гарантия безопасности при отказе), поэтому Единственное, что мы можем сделать, это объявить его.
Это часть более общего наблюдения, что мы заинтересованность в самом деле - это надежность безопасности в компонентах программы, а чем безопасность исключений. Независимо от того, используете ли вы исключения, возврат ошибки значения, errno или что
когда-либо еще, рассуждения об основных (без утечки, сохранения инвариантов), сильной (фиксации или откат) и гарантии никогда не должны сохраняться.
Итак, если мы возьмем аналогичную позицию, то, похоже, ответ будет отрицательным, если не подходит для использования noexcept
, и это похоже на то, где вы наклоняетесь. Я не думаю, что это четкий ответ.
Он также отмечает предложение N3248: noexcept Предотвращает проверку библиотек. Это, в свою очередь, послужило основой для N3279: Консервативное использование noexcept в Библиотеке. Этот документ определяет узкие и широкие контракты, как и N3248:
Широкие контракты
Широкий контракт для функции или операции не укажите любое поведение undefined. Такой договор не имеет никаких предварительных условий: Функция с широким контрактом не предусматривает дополнительного времени выполнения ограничений на его аргументы, на любое состояние объекта или на любые внешние глобальное государство. Примеры функций, имеющих широкие контракты, vector:: begin() и vector:: at (size_type). Примеры функции, не имеющие широкого контракта, будут иметь вектор:: front() и vector:: operator [] (size_type).
Узкие контракты
Узкий контракт - это контракт, который не является широким. Узкие контракты на функции или операции приводят к поведению undefined при вызове в что нарушает документированный контракт. Такой договор указывает, по крайней мере, одно предварительное условие, включающее его аргументы, объект состояния или некоторого внешнего глобального состояния, такого как инициализация статический объект. Хорошие примеры стандартных функций с узкими контракты: vector:: front() и vector:: operator [] (size_type).
и рекомендует:
Каждая функция библиотеки имеет широкий контракт, который согласен с LWG не может бросать, следует отмечать как безоговорочно noexcept.
и подразумевает, что функции с узкими контрактами не должны быть noexcept
, которые подкреплены LWG issue 2337, в котором говорится:
[...] Эти соображения дизайна переопределяют нашу общую политику, исключая узкоконтрактные функции. [...]
Итак, если мы хотим быть консервативными и следовать стандартной библиотечной практике, тогда казалось бы, что operator[]
не имеет широкого контракта, он не должен быть помечен noexcept
.