GCC правильно;Виртуальная функция в производном классе не может иметь более слабого спецификатора исключения, чем функция, переопределяемая в базовом классе.Причина довольно ясна: если это было разрешено, вызывающая сторона может вызывать переопределяющую функцию через указатель базового класса, таким образом, получение функции не учитывает контракт исключения из статического типа, через который она вызывается.
В MSVC это работает только потому, что его поддержка спецификаторов исключений чрезвычайно ограничена - он фактически анализирует только throw()
, все остальные описатели исключений просто игнорируются.
Теперь, учитывая, что спецификаторы исключений, кромеthrow()
(AKA nothrow
):
- игнорируются в MSVC.
- все равно не рекомендуется использовать стандарт.
- широко расценивается как ошибка, посколькуони покупают вам практически нулевую безопасность во время компиляции - они сводятся к тому, чтобы обернуть все аннотированные функции большим
try
и вызывать std::unexpected
, если выбрасывается что-то неожиданное, - и даже для проверенных исключений в стиле Java это широко обсуждаетсяесли проблема действительно того стоит;
вам, вероятно, следует отказаться отм в целом и никогда не оглядывайся назад.