具有两个类似catch部分的代码的异常处理行为

cdu*_*mie 3 c++

我有一个我只为练习目的创建的短代码,我想检查如果我有两个catch部分会发生什么,一个是通过引用捕获(int&)而第二个是按值(int)捕获.问题是,当我运行此代码时,即使我抛出"常规"整数,也会出现按引用捕获.为什么会这样?

注意:当我在MSVS17上编译它时,我得到错误C2313:

'int':由第15行的引用('int&')捕获

但是当我使用在线编译器时它工作得很好.

当我删除其中一个catch部分时,即使在MSVS17中它也可以正常工作,但是,为什么是调用引用的catch部分而不是另一个

#include <iostream>
using namespace std;

int main()
{
    int i = 5;
    try {
        if (i)
            throw(i);
        return 0;
    }

    catch (int &)
    {
        cout << "Int&";
    }

    catch (int)
    {
        cout << "Int";
    }
}
Run Code Online (Sandbox Code Playgroud)

L. *_* F. 5

TL; DR

catch匹配中没有优先权.A catch匹配或不匹配.参考是匹配.

不是那么简短的答案

cppreference说:

当复合语句中的任何语句抛出类型E的异常时,它将根据handler-seq中每个catch子句的形式参数T的类型与列出catch子句的顺序进行匹配.

即第一场比赛被选中(没有"更好"或"更差"的概念; catch或者是否匹配.)

进一步说:

如果满足以下任何条件,则例外是匹配:

  • ...
  • T是对(可能是cv限定的)E的左值引用
  • ...

因此,catch(int&)是一场比赛; catch(int)甚至没有机会被考虑.

马丁邦纳的榜样

Martin Bonner提供了一个很好的例子来让你理解这一点,并且OP完全理解它:

try {
    throw 5;
}
catch (int) { // int first
    // ...
}
catch (int&) { // this is not even considered!
    // ...
}
Run Code Online (Sandbox Code Playgroud)

  • 同样,如果一个人写了“ try {throw 5; } catch(int){...} catch(int&){...}`将会执行`int` catch。 (2认同)