重新定义包含相同异常的exception_ptr的多个实例

时间:2015-04-26 12:47:01

标签: c++ exception c++11

以下代码段的行为是否定义明确?

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)可以复制?

1 个答案:

答案 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()时,复制对象所需的信息不存在。