以下代码段的行为是否定义明确?
std::exception_ptr eptr;
try {
...
} catch (...) {
eptr = std::current_exception();
}
std::exception_ptr eptr2(eptr);
std::vector<std::exception_ptr> eptrs{eptr, eptr2};
for (auto& exc: eptrs) try {
std::rethrow_exception(exc);
} catch(std::exception& e) {
std::cout << e.what() << '\n';
}
如果是这样,这是否要求异常对象本身(不仅仅是exception_ptr)可以复制?
答案 0 :(得分:2)
我无法引用该标准,但查看documentation的std :: exception指针,它指出:
它是一个类似于共享指针的类型:只要至少有一个exception_ptr指向它,指向的异常保证保持有效,可能会延长其生命周期超出catch语句的范围或跨线程。
可以复制exception_ptr本身:
被复制,包括被复制空指针值(或nullptr)。
所以是的,行为是定义的。 由于它是共享指针式类型,因此对包含的异常对象没有复制要求
这article进一步解释了这一点:
该功能的原始提议要求在使用std :: current_exception捕获异常时复制该异常,但是在使用“Itanium ABI”(实际上也用于其他平台,例如64)的实现者的压力下-bit x86 linux和MacOSX),该要求被减少,以允许引用计数异常。他们引用的问题是 ABI没有存储异常对象的复制构造函数,所以当你调用std :: current_exception()时,复制对象所需的信息不存在。