С++ пропускает спецификатор `noexcept` по сравнению с `noexcept (false)`, каково их точное значение?

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

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


person Peregring-lk    schedule 21.04.2015    source источник
comment
Если вы принимаете noexcept(false) за противоположность noexcept(true), ссылка отвечает на все вопросы.   -  person chris    schedule 21.04.2015


Ответы (2)


Указав 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).

person Angew is no longer proud of SO    schedule 21.04.2015
comment
@Deduplicator Изменил формулировку функций, но я не могу найти ссылку на конструкторы, ведущие себя так же. Можно номер абзаца? - person Angew is no longer proud of SO; 21.04.2015
comment
@Deduplicator Только в том случае, если он не предоставлен пользователем (т. Е. Неявно объявлен или явно установлен по умолчанию при первом объявлении). См. [dcl.fct.def.default]/p2, [кроме.spec]/14. - person T.C.; 21.04.2015
comment
Вы также пропустили функции освобождения, которые по умолчанию noexcept(true). - person T.C.; 21.04.2015

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

person Sebastian Redl    schedule 21.04.2015