Почему декларация исключения catch позволяет скользящие круглые скобки?
Я столкнулся с некоторым кодом на С++, который выглядит следующим образом:
class exception {};
int main()
{
try {
throw exception();
} catch (exception()) {
// ...
}
}
Обратите внимание на дополнительный набор круглых скобок в catch (exception())
. Согласно Compiler Explorer, он скомпилирован в один и тот же объектный код, как если бы он был написан с помощью catch (exception &)
.
На каком основании разрешен дополнительный набор круглых скобок и какая часть стандарта позволяет это? Насколько мне известно, предложение catch
требует спецификатора типа, но exception()
не похоже на спецификатор типа.
Ответы
Ответ 1
Объявления обработчика исключений работают как декларации функций, в параметрах массива и типа функции настраиваются указатели. (То есть, массивы и функции не могут быть выброшены или пойманы "по значению".) В частности, [except.handle] p2 говорит:
Обработчик типа "массив из T
" или тип функции T
настраивается как "указатель на T
".
Итак, catch (exception())
идентичен catch (exception(*p)())
.
Ответ 2
exception()
объявляет функцию. Per except#nt:handler, объявление-декларация содержит декларатор. Объявление является типом декларатора. Легко это видеть, потому что exception(int)
тоже отлично работает. Обратите внимание, что объявление-исключение происходит точно так же, как объявление параметра, поэтому оно работает точно так же, как объявление функции в параметре.