为什么标准不允许引用不完整的异常类型?

Aco*_*gua 9 c++ exception-handling language-lawyer

从C++ 17标准(草案),18.3.1:

[...]异常声明不得表示指向不完整类型的指针或引用[...]

禁止通过引用来捕获不完整类型的原因是什么?

如果函数参数是通过引用传递的,那么只有在函数实际访问接收到的对象时才需要完整类型,但是它可以很好地将参数传递给另一个函数,而不需要知道任何类型的函数.

我不明白为什么这应该与异常不同 - 异常数据本身可能驻留在任何适当的位置,并且在(unwinded up to the handler)堆栈中我们找到引用.精细.如果处理程序现在只能从异常类型中拖动足够的信息,为什么需要知道完整的定义呢?

那么我错过了什么?

YSC*_*YSC 10

struct Alice;
struct Bob;

int main() {
    try {
        throwAlice(); // extern
    } catch (Bob&) {
        return 0;
    }
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

以下程序返回什么?0或1或鼻子恶魔?嗯,这取决于Alice继承Bob.

要处理异常捕获机制,编译器必须在编译时拥有该信息.Bob应该是一个完整的类型.

原因解释如下:

[except.handle]/15

异常声明声明的类型cv Tcv T&[YSC:here,cv T& = Bob&] 声明的变量是从E [YSC:here,E = Alice] 类型的异常对象初始化的,如下所示:

  • 如果T是基类E,则从异常对象的相应基类子对象复制初始化变量;
  • 否则,该变量是从异常对象复制初始化的.

这确认编译器需要知道在编译时是否Bob继承Alice:Bob必须是完整类型.

  • 你知道,有时标准强加的东西没有明显的原因,比如[在C++ 98中你不能使用函数中定义的类型来实例化模板](http://coliru.stacked-crooked.com/a/f880d2689c887a00"demo"),已在C++ 11中放宽,因此lambda是相关的. (2认同)