【问题标题】:Why does a catch exception-declaration allow trailing parentheses?为什么 catch 异常声明允许使用尾括号?
【发布时间】:2018-07-29 05:46:21
【问题描述】:

我遇到了一些如下所示的 C++ 代码:

class exception {};

int main()
{
    try {
        throw exception();
    } catch (exception()) {
        // ...
    }
}

注意catch (exception()) 中的额外括号。根据Compiler Explorer,它被编译为与使用catch (exception &) 编写的相同的目标代码。

在什么基础上允许额外的括号集?标准的哪一部分允许这样做?据我所知,catch 子句需要类型说明符,但 exception() 似乎不像类型说明符。

【问题讨论】:

  • 在我看来就像一个函数声明。同样的原因exception(int) 有效。
  • 看起来像是一个构造函数调用。
  • 也试试catch (int[5])
  • @Ayush 你不能调用构造函数,尽管语法让你相信。

标签: c++ exception-handling try-catch


【解决方案1】:

异常处理程序声明像函数声明一样工作,其中数组和函数类型参数被调整为指针。 (也就是说,数组和函数不能“按值”抛出或捕获。)具体来说,[except.handle]p2 说:

类型为“T”的处理程序或函数类型T 被调整为“指向T”的类型。

所以catch (exception())catch (exception(*p)()) 相同。

【讨论】:

  • 嗯,对,所以它声明了一个不带参数的未命名函数,它返回exception类型的值。
  • 异常在哪里捕获?
  • @0x499602D2:在我的问题示例中,它不是。 catch 子句捕获的东西与抛出的完全不同。
  • @GregHewgill:不,它没有声明一个函数。相反,它声明了一个类似“参数”的变量,没有名称,其类型是“指向函数的指针”。 (在 C++ 中,您不能将函数声明为较大语句的一部分。我认为在 C 中您可以做一些非常神秘的事情,但在 C++ 中,函数声明需要是独立的语句。)
  • @KerrekSB:是的,对不起我草率的措辞。当然不是一个实际的函数,而是一个函数指针类型。
【解决方案2】:

exception() 正在声明一个函数。根据except#nt:handlerexception-declaration 包含 declaratorfunction declaration 是一种声明符。很容易看到这一点,因为exception(int) 也可以正常工作。请注意,exception-declaration 恰好与 parameter-declaration 完全相同,因此它的工作方式与在参数中声明函数完全相同。

【讨论】:

    猜你喜欢
    • 2021-02-02
    • 1970-01-01
    • 2018-08-15
    • 2015-06-22
    • 2012-07-20
    • 2011-07-14
    相关资源
    最近更新 更多