C++ catch子句非强制复制消除:两个catch子句谁可触发?
问题解答
参考规则
在以下情况下,编译器允许但不要求省略类对象的复制和移动(C11起)构造,即使复制/移动(C11起)构造函数和析构函数有可观察的副作用。
在catch子句中,当参数与抛出的异常对象类型相同(忽略cv限定符)时,异常对象的复制会被省略,catch子句体直接访问异常对象,就像通过引用捕获一样(无法从异常对象移动,因为它始终是左值)。
代码场景分析
你的代码中,makeObj函数在内存分配失败时会抛出std::bad_alloc类型的异常。
- 第一个catch子句
catch(std::exception e):抛出的异常实际类型是std::bad_alloc,而std::exception是它的基类,两者类型并不匹配。不符合规则中“参数与抛出的异常对象类型相同”的要求,因此不会触发复制消除。此时会执行std::exception的复制构造函数,对bad_alloc对象进行切片复制。 - 第二个catch子句
catch(std::bad_alloc e):抛出的异常对象类型与catch参数类型完全一致(忽略cv限定符),满足规则中的条件,因此编译器允许省略异常对象的复制构造,直接访问原异常对象。
结论:只有第二个catch子句可能触发复制消除,第一个不会。
内容的提问来源于stack exchange,提问作者Vinod
相关产品推荐
相关产品推荐

