Разрешены ли возможности реализации стандартной библиотеки С++ для упрощения каких-либо спецификаций?

В соответствии со стандартом С++ реализация стандартной библиотеки С++ позволила укрепить спецификации noexcept методов и других функций стандартной библиотеки С++, определенных стандартом?

Например, если в стандарте С++ определенная функция std::f как void f(); являются стандартными реализациями библиотек, разрешенными вместо нее реализовать void f() noexcept;?

Ответ 1

Стандарт говорит "да":

§ 17.6.5.12.1 Ограничения при обработке исключений [res.on.exception.handling]

  • Любая из функций, определенных в стандартной библиотеке С++, может сообщить об ошибке, выбрасывая исключение типа, описанного в его Throws:. Реализация может усилить спецификацию исключений для не виртуальной функции, добавив спецификацию noexcept без бросания.

[...]

  1. Операции деструктора, определенные в стандартной библиотеке С++, не должны исключать исключения. Каждый деструктор в стандартной библиотеке С++ должен вести себя так, как если бы у него была спецификация исключений для исключения метаданных. Любой другой функции, определенные в стандартной библиотеке С++, которые не имеют спецификации исключения, могут вызывать исключения, определенные реализацией, если не указано иное. Реализация может укрепить это неявную спецификацию исключений путем добавления явного.

(Comma 4, по-видимому, просто позволяет четко указывать спецификацию исключения и предупреждать, что отсутствие явной спецификации исключения означает, что реализации разрешено что-либо бросать).


Честно говоря, я не понимаю, почему это разрешено, а добавление constexpr не является (§ 17.6.5.6). Они выглядят как две стороны одной и той же медали - с использованием свойств типа и SFINAE вы можете иметь код, который показывает разные типы поведения, в зависимости от используемой вами стандартной библиотеки (если он отмечает некоторые функции как noexcept/constexpr, или если это не так), и это побеждает цели, имеющие стандарт в первую очередь...