如何在运行时确定exception_ptr指向的异常类型?
在C++ 11及更高版本中,可以使用current_exception()
检索到当前异常的exception_ptr
。是否有可能在运行时确定所指向的异常的类型?如何在运行时确定exception_ptr指向的异常类型?
更确切地说,如何获得exception_ptr
所指异常的type_info
的引用?我知道根据类型catch
是可能的,但程序员需要为所有可能的异常类型编写catch
块,但这不是解决此问题的方案。
try {
userProvidedRuntimePlugin.executeAction(); // May throw anything
} catch (...) {
auto e = std::current_exception();
std::type_info & info = /* ??? */;
std::cerr << "Exception of type " << info.name() << " thrown." << std::endl;
}
尝试类似如下:
#include <cxxabi.h>
using namespace __cxxabiv1;
std::string util_demangle(std::string to_demangle)
{
int status = 0;
char * buff = __cxxabiv1::__cxa_demangle(to_demangle.c_str(), NULL, NULL, &status);
if (!buff) return to_demangle;
std::string demangled = buff;
std::free(buff);
return demangled;
}
try
{
/* .... */
}
catch(...)
{
std::cout <<"exception type: '" << util_demangle(abi::__cxa_current_exception_type()->name()) << "'\n";
}
谢谢!你的回答实际上导致我也在SO上发现了一些我的问题的重复。例如,我的问题似乎也[这里回答](http://stackoverflow.com/a/28538250/3919155)。欢迎来到堆栈溢出! :-) – jotik
'__cxa_demangle'可能会返回0,然后'std :: string demangled = buff'会导致应用程序崩溃。 –
“崩溃你的应用程序” - 不一定:如果buff == 0,则抛出std :: logic_error。 –
不,很遗憾,您将无法检测到异常类型。 您auto e
变量将仅仅是类型std::exception_ptr e
的。如果你想不同的行为在特定类型的异常,你需要做的就是抓住这个例外在第一什么的。例如:
try{
userProvidedRuntimePlugin.executeAction(); // May throw anything
} catch (std::exception e) {
//handle std::exception
} catch (your::exception e2) {
//handle your::exception
}catch (...) {
std::exception_ptr e = std::current_exception();
cout << "unknown exception" << endl;
std::rethrow_exception(e); // for example
}
,如果你不知道该怎么在这个水平上一个选项与意外的异常做重新抛出它使用std::rethrow_exception(e);
没有,类型信息不能直接从异常指针中获得。但是,真正的用例是什么?你总是可以重新投掷和捕捉。 –
@KerrekSB我只能通过类型捕获,如果我知道异常的类型或异常的基类的类型,并非总是如此。很抱歉,由于法律原因,我无法分享有关真实用例的更多信息。 – jotik
“真实”并不意味着“你在做什么”。它可以很好地指代包含与您的真实项目相同的*设计元素的人工构建场景。你甚至不必指出这个元素是什么。 “真实”仅仅意味着你不应该给我们一条线,而是说它不会做你想做的事。在C++中有许多你不能做的特殊事情,但这本身并不有趣。问题是,是否有什么你可能真的想要因为它而无法完成。 –