什么是“扔”;在一个拦截区外吗?

时间:2010-04-22 15:16:53

标签: c++

我只是偶然发现了这段代码:

void somefunction()
{
   throw;
}

我想知道:这是什么意思?


我将问题标记为C ++和Visual C ++,因为我不知道答案。答案可能与标准或特殊的Visual C ++扩展或忽略标准的Visual C ++有关。这就是为什么我认为这两个标签都是合理的。

4 个答案:

答案 0 :(得分:30)

意图可能是somefunction()只能从某个catch块内部调用。在这种情况下,执行throw;时会有一个活动异常,在这种情况下会重新抛出当前异常,由可以处理该异常类型的下一个外部处理程序捕获。

如果异常未激活时执行throw;,则会调用terminate()(N4810,§[expr.throw] / 4)。

答案 1 :(得分:9)

重新抛出当前活动的异常。从catch-block中调用它(可能是间接的)是有意义的。这样:

#include <iostream>
using namespace std;

void f() {
    throw;
}

int main() {
    try {
        try {
            throw "foo";
        }
        catch( ... ) {
            f();
        }
    }
    catch( const char * s ) {
        cout << s << endl;
    }
}

打印“foo”。

答案 2 :(得分:5)

对于throw,“外部”或“内部”catch块的概念是在运行时术语中定义的,而不是在您似乎假设的编译时术语中定义的。因此,如果在throw块的运行时上下文中执行catch的运行时,则throw按预期工作。否则,将调用terminate()

事实上,如果你仔细研究一下如何在语言规范中定义C ++异常,那么很多关于它们的东西都是在运行时术语中定义的。有时它甚至看起来像是非C ++。

答案 3 :(得分:3)

人们已经解释了它的含义,但知道你为什么会看到它可能是有用的。这是构建“泛型”异常处理程序的有用方法,该异常处理程序根据类型处理异常,以减少重复代码的数量。

因此,如果我们采用Neil's example并展开f()可能正在做的事情,我们可能最终会得到一个类似LogKnownException()功能的实现,我在{{3}中提出了这个功能。 }}。

如果您正在一个团队中工作,他们喜欢在所有地方记录所有异常情况,那么在所有这些地方(甚至更糟糕的是宏)上都有大量的捕获块,你可以拥有一个简单的捕获看起来像这样的块

catch(...)
{
   LogKnownException();
}  

虽然我希望我将之前的LogKnownException()示例更改为只允许其不想记录的异常传播并继续以未处理的方式继续。

我并不是说这一定是件好事,只是指出这是你可能会看到使用的构造的地方。