С++ опускает спецификатор noexcept` против `noexcept (false)`, каков его точный смысл?

Если я отмечаю функцию как noexcept(false) или любое другое выражение, которое оценивает значение false, что это значит? (1) Я предоставляю компилятору, что функция может генерировать исключение?, (2), или я ничего не знаю о том, может ли он генерировать исключения или нет?

И, наконец, если я опускаю спецификатор noexcept, он эквивалентен noexcept(false) или эквивалентен только указанному выше значению (2) n?

Ответы

Ответ 1

Указывая noexcept(true), вы утверждаете, что функция никогда не выдает исключения. Указав noexcept(false) или не указывая ничего, вы не утверждаете, что функция никогда не генерирует исключения.

Итак, это в основном ваш оператор (2), но обратите внимание, что для компилятора это эквивалентно вашему утверждению (1). Если компилятор не уверен, что функция не будет бросать, он должен предположить, что он может.

Соответствующим битом стандарта является С++ 11 15.4/12:

Функция без спецификации исключения или с спецификацией исключения формы noexcept(constant-expression), где выражение констант false допускает все исключения. Спецификация исключения не бросать, если он имеет вид throw(), noexcept или noexcept(constant-expression), где константное выражение дает true. Функция с исключительной спецификацией исключения не допускает никаких исключений.

Есть только два отклонения от этого правила. Один из них - деструкторы, поэтому никакая спецификация исключений для деструктора не дает деструктору той же спецификации исключения, что и созданная по умолчанию. То есть noexcept(true) тогда и только тогда, когда все функции, которые будут непосредственно вызываться из созданного по умолчанию деструктора, noexcept(true).

Другая функция - освобождение (operator delete) — функция деаллоляции без явной спецификации исключения рассматривается как noexcept(true).

Ответ 2

Опускание спецификатора noexcept эквивалентно noexcept(false), за исключением деструкторов, где опускание спецификатора означает, что компилятор выводит из членов и базовых классов.