noexcept
указывает, что функция предназначена для того, чтобы не генерировать исключение, гарантию, которую вы, как разработчик, предоставляете, которая не применяется компилятором. Поэтому использовать его в ситуации, когда ваша функция вызывает функции, которые могут генерировать исключения, которые вы сами не поймаете, — это плохо.
Весь диапазон спецификаторов throw()
был удален, поскольку спецификаторы исключений были менее оптимальными в C++, см.: Разница между спецификатором throw() C++03 C++11 noexcept
Преимущество noexcept
заключается в том, что не указывается, какое исключение выброшено, а скорее выдается ли исключение или нет. Он принимает параметр, который может быть false
, если вы ожидаете, что функция выдаст исключение.
Использование этого может быть, например, в структуре унаследованного класса, где один суперкласс хочет «принудить» к унаследованному классу, что конкретной виртуальной функции не разрешено генерировать исключение. Более того, компилятор может использовать эту информацию для оптимизации.
noexcept
также является оператором, который может оценивать выражение и возвращать значение, может ли это выражение вызвать исключение или нет, в соответствии с § 5.3.7.
5.3.7 оператор noexcept [выражение.unary.noexcept]
1 Оператор noexcept определяет, может ли оценка его операнда, который является невычисленным операндом (раздел 5), вызвать исключение (15.1). noexcept-выражение: noexcept (выражение)
2 Результатом операции noexcept является константа типа bool и значение rvalue.
3 Результат оператора noexcept будет ложным, если в потенциально оцениваемом контексте выражение будет содержать
— потенциально вычисляемый вызов функции, функции-члена, указателя на функцию или указателя на функцию-член, который не имеет негенерирующей спецификации исключения (15.4), если вызов не является константным выражением (5.19),
— потенциально оцениваемое выражение throw (15.1),
— потенциально оцениваемое выражение dynamic_cast dynamic_cast(v), где T — ссылочный тип, требующий проверки во время выполнения (5.2.7), или
— потенциально вычисляемое выражение typeid (5.2.8), примененное к выражению glvalue, тип которого является типом полиморфного класса (10.3).
В противном случае результат будет истинным.
Я не могу объяснить возможные оптимизации, а также Скотт Мейерс: http://aristeia.com/EC++11-14/noexcept%202014-03-31.pdf из его сообщения в блоге: Объявлять функции noexcept всякий раз, когда это возможно?
Разница между раскручиванием стека вызовов и, возможно, его раскручиванием оказывает удивительно большое влияние на генерацию кода. В функции без исключений оптимизаторам не нужно поддерживать стек времени выполнения в неразматываемом состоянии, если исключение будет распространяться за пределы функции, а также они не должны гарантировать, что объекты в функции без исключений уничтожаются в порядке, обратном построению, если исключение покидает функцию. . В результате появляется больше возможностей для оптимизации не только внутри тела функции noexcept, но и на сайтах, где эта функция вызывается. Такая гибкость присутствует только для функций noexcept. В функциях со спецификацией исключения «throw()» его нет, как и в функциях вообще без спецификации исключения.
person
Tommy Andersen
schedule
19.10.2015