C++ `std::terminate`如何知道对`std::exception`进行特殊处理?

C++ `std::terminate`如何知道对`std::exception`进行特殊处理?,c++,C++,这个 如果我取消注释该注释,则死亡消息将变为: terminate called after throwing an instance of 'A' Aborted (core dumped) std::terminate如何专门处理std::exceptions 我如何在自己的set\u terminate中模拟这一点?我试过了 terminate called after throwing an instance of 'A' what(): this is A Aborted (cor

这个

如果我取消注释该注释,则死亡消息将变为:

terminate called after throwing an instance of 'A'
Aborted (core dumped)
std::terminate
如何专门处理
std::exception
s

我如何在自己的
set\u terminate
中模拟这一点?我试过了

terminate called after throwing an instance of 'A'
what():  this is A
Aborted (core dumped)
/。。。
int main(){
std::set_terminate([](){
printf(“抛出异常\n”);
std::exception_ptr eptr=std::current_exception();
std::exception*ptr=动态广播(eptr);
如果(ptr)
放置(ptr->what());
});
扔一个{};
}

但是它不会编译,因为有
dynamic\u cast
行。

最有可能的原因是它只是尝试
dynamic\u cast
将它转换为
std::exception
,并调用虚拟
what()
方法,如果动态转换成功。

std::terminate
所做的事情可以用以下方法近似模拟:

//...
int main(){
  std::set_terminate([](){
      printf("exception thrown\n");
      std::exception_ptr eptr = std::current_exception();
      std::exception* ptr =  dynamic_cast<std::exception*>(eptr);
      if (ptr) 
        puts(ptr->what());
  });
  throw A{};
}


感谢您为我指明了正确的方向。

显然是这样。@user4815162342有趣的是,我得到了
what():
行,即使我在链接文章中使用
-fno-rtti
@PSkocik进行编译,也说明即使禁用了rtti,也会使用rtti的某些部分,这些部分是使异常工作的必要条件。通常这样的事情是使用编译器魔法完成的:内置和编译器特定的代码<代码>标准::终止在运行库的深处实现。libstdc++只是抛出当前异常并尝试捕获
std::exception
。源代码:@PSkocik是的,链接文章明确指出了这一点。根据作者的发现,
-fno rtti
仅禁用前端功能,如
typeid
,但实现RTTI的meachanism仍然用于后台异常。结果表明,它无法尝试将
dynamic\u cast
转换为
std::exception
,因为
dynamic\u cast
仅在对象处于同一层次结构时才起作用。如果不是,它甚至不会编译。@PSkocik:
dynamic\u cast
ing
exception\u ptr
没有意义,因为它是一个不透明类型,而不是一个文本指针。请注意,您可以替换
std::rethrow\u exception(std::current\u exception()
仅使用
抛出
。虽然它在
捕获
之外看起来不合适,但它甚至在C++98上也能工作。你比我快了3或4秒。:)以前的版本仍然很有趣,因为我了解了
std::rethrow_异常
std::current_异常
,这两个都是C++11中的新功能。@user4815162342在您的注释前几秒钟就这样做了。您可能还需要一个
catch(…)
--否则,抛出不属于子类的
std::exception
可能会导致调用终止处理程序的循环。从声明的
noexcept
抛出异常调用
std:unexpected()
,默认情况下只调用
std::terminate()
。。。
//...
int main(){
  std::set_terminate([](){
      printf("exception thrown\n");
      std::exception_ptr eptr = std::current_exception();
      std::exception* ptr =  dynamic_cast<std::exception*>(eptr);
      if (ptr) 
        puts(ptr->what());
  });
  throw A{};
}
std::set_terminate([](){
  puts("exception thrown"); 
  //^skip the demangling of the typeid that's normaly done
  try { throw; } 
    catch(const std::exception& e){ puts(e.what()); }
    catch(...){}
  //^rethrow and catch
});