介紹的類型:給定C++演繹出嵌套異常
:
struct X : std::runtime_error {
using std::runtime_error::runtime_error;
};
當我們調用std::throw_with_nested(X("foo"))
,什麼是真正拋出不是X
。它是從X
和std::nested_exception
派生的某種類型。
因此,下面的斷言將失敗:
const std::type_info *a = nullptr, *b = nullptr;
try
{
throw X("1");
}
catch(X& x) {
a = std::addressof(typeid(x));
try {
std::throw_with_nested(X("2"));
}
catch(X& x) {
b = std::addressof(typeid(x));
}
}
assert(std::string(a->name()) == std::string(b->name()));
我想這樣做是推斷,這兩個例外是相關的。
第一次嘗試:
std::type_index
deduce_exception_type(const std::exception* pe)
{
if (auto pnested = dynamic_cast<const std::nested_exception*>(pe))
{
try {
std::rethrow_exception(pnested->nested_ptr());
}
catch(const std::exception& e)
{
return deduce_exception_type(std::addressof(e));
}
}
else {
return typeid(*pe);
}
}
失敗的原因是std::nested_exception::nested_ptr()
返回一個指向下一個異常的路線,而不是當前異常的X
接口。
我正在尋找(便攜式)想法和解決方案,使我可以從標準庫在std::rethrow_exception
期間拋出的'未知名稱的異常'中恢復typeid(X)。
C++ 14和C++ 1z都很好。
爲什麼?:
因爲我希望能夠解開一個完整的異常層次和跨RPC會議遞交的,完整的異常類型的名稱。
我理想的情況是不想編寫一個以系統中每個異常類型爲特徵的catch塊,而這個異常類型必須通過派生深度弱排序。
的預期功能(以及爲什麼我的方法是行不通的插圖)另一個例子:
const std::type_info *b = nullptr;
try
{
throw std::runtime_error("1");
}
catch(std::exception&) {
try {
std::throw_with_nested(X("2"));
}
catch(X& x) {
// PROBLEM HERE <<== X& catches a std::_1::__nested<X>, which
// is derived from X and std::nested_exception
b = std::addressof(typeid(x));
}
}
assert(std::string(typeid(X).name()) == std::string(b->name()));
@ Jarod42指出,謝謝。正如你所看到的,我在代碼中使用type_index。我將更新問題以按名稱()比較a和b。 –
注意你最後想要展示的東西,你有'std :: runtime_error' vs'X' ... – Jarod42
@ Jarod42沒錯。 X正在封裝一個嵌套的runtime_error。我想從它的未命名的實際類型中推導出X(包裝器)的類型。 –