具有两个类似catch部分的代码的异常处理行为
Exception handling behaviour of code with two similar catch sections
我有一个简短的代码,我只是为了练习而创建的,我想检查如果我有两个catch部分,一个通过引用捕获(int&
),另一个通过值捕获(int
),会发生什么。问题是,当我运行此代码时,即使我抛出了"正则"整数,也会出现引用捕获。为什么会发生这种情况?
注意:当我在MSVS17上编译这个时,我得到错误C2313:
't':在第15行上被引用('t&')捕获
但当我使用在线编译器时,它工作得很好。
当我删除其中一个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";
}
}
TL;DR
catch
-匹配没有优先级。catch
匹配或不匹配。引用是匹配的。
答案不那么简短
cppreference说:
当复合语句中的任何语句抛出E类型的异常时,它将按照catch子句的列出顺序,与处理程序seq中每个catch子句形式参数T的类型进行匹配。
即选择第一个匹配(不存在"更好"或"更差"匹配的概念;catch
匹配与否。)
此外,它还说:
如果以下任何一项为真,则异常为匹配:
- T是E的左值参考(可能是cv限定的)
因此,catch(int&)
是匹配的;catch(int)
甚至没有机会被考虑。
马丁·邦纳的例子
Martin Bonner提供了一个很好的例子来让你理解这一点,OP也完全理解它:
try {
throw 5;
}
catch (int) { // int first
// ...
}
catch (int&) { // this is not even considered!
// ...
}
相关文章:
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- Firebase C++VS2018 SDL2-在Firebase::app::create(..)上执行异常处理
- 使用 stoi 功能进行异常处理
- 子系统中的异常处理:本机
- 与异常处理程序中的操作员<<不匹配
- 数组 C++ 上的异常处理程序
- 使用 googletest 测试嵌入式C++代码时处理外设寄存器的重复符号
- 为什么我的代码无法处理大型数组输入(>10000)?
- 是否正确处理了此代码异常?
- 在C++中重用异常处理代码
- 具有两个类似catch部分的代码的异常处理行为
- 是否可以对构造函数抛出异常的对象进行异常处理,该对象的异常处理接近其基于堆栈的代码创建
- 在异常处理中,对性能的影响会随着 try 部分中的代码量而增长
- 以下哪个异常处理代码段有效,原因
- 使用不支持异常处理的代码(C++/LLVM)进行链接
- SWIG生成的代码未处理或引发异常
- 我应该在现有的代码库中添加异常处理吗?
- C代码中的C++异常处理
- 使用异常处理库的(可能更改的)错误代码