gpt4 book ai didi

c++ - 如何调用 std::exception_ptr 上的 what()

转载 作者:IT老高 更新时间:2023-10-28 12:50:26 29 4
gpt4 key购买 nike

这是我的代码。

try
{
// code throws potentially unknown exception
}
catch (...)
{
std::exception_ptr eptr = std::current_exception();
// then what ?
}

理想情况下,如果它是 std::exception,我想获取与异常关联的字符串。

最佳答案

// then what ?

这是什么:

#include <exception>
#include <stdexcept>
#include <iostream>
#include <string>

std::string what(const std::exception_ptr &eptr = std::current_exception())
{
if (!eptr) { throw std::bad_exception(); }

try { std::rethrow_exception(eptr); }
catch (const std::exception &e) { return e.what() ; }
catch (const std::string &e) { return e ; }
catch (const char *e) { return e ; }
catch (...) { return "who knows"; }
}

int main()
{
try { throw std::runtime_error("it's success!"); }
catch (...) { std::cerr << "Here is WHAT happened: " << what() << std::endl; }

try { throw 42; } catch (...) { std::cerr << "and now what: " << what() << std::endl; }
}

打印的内容:

Here is WHAT happened: it's success!
and now what: who knows

http://coliru.stacked-crooked.com/a/1851d2ab9faa3a24

所以这允许在 catch-all 子句中获取 what

但是如果异常是嵌套的呢???这是什么:

std::string what(const std::exception_ptr &eptr = std::current_exception());

template <typename T>
std::string nested_what(const T &e)
{
try { std::rethrow_if_nested(e); }
catch (...) { return " (" + what(std::current_exception()) + ")"; }
return {};
}

std::string what(const std::exception_ptr &eptr)
{
if (!eptr) { throw std::bad_exception(); }

try { std::rethrow_exception(eptr); }
catch (const std::exception &e) { return e.what() + nested_what(e); }
catch (const std::string &e) { return e ; }
catch (const char *e) { return e ; }
catch (...) { return "who knows"; }
}

使用 here 中的示例:

#include <fstream>

...

// sample function that catches an exception and wraps it in a nested exception
void open_file(const std::string& s)
{
try {
std::ifstream file(s);
file.exceptions(std::ios_base::failbit);
} catch(...) {
std::throw_with_nested( std::runtime_error("Couldn't open " + s) );
}
}

// sample function that catches an exception and wraps it in a nested exception
void run()
{
try {
open_file("nonexistent.file");
} catch(...) {
std::throw_with_nested( std::runtime_error("run() failed") );
}
}

int main()
{
try { throw std::runtime_error("success!"); }
catch (...) { std::cerr << "Here is WHAT happened: \"" << what() << '\"' << std::endl; }

try { run(); }
catch (...) { std::cerr << "what happened for run: \"" << what() << '\"' << std::endl; }
}

打印的内容:

Here is WHAT happened: "success!"
what happened for run: "run() failed (Couldn't open nonexistent.file (basic_ios::clear))"

http://coliru.stacked-crooked.com/a/901a0c19297f02b5

但是如果递归太深怎么办?如果堆栈溢出怎么办?优化了什么:

#include <typeinfo>

template <typename T>
std::exception_ptr get_nested(const T &e)
{
try
{
auto &nested = dynamic_cast<const std::nested_exception&>(e);
return nested.nested_ptr();
}
catch (const std::bad_cast &)
{ return nullptr; }
}

#if 0 // alternative get_nested
std::exception_ptr get_nested()
{
try { throw ; }
catch (const std::nested_exception &e) { return e.nested_ptr(); }
catch (...) { return nullptr ; }
}
#endif

std::string what(std::exception_ptr eptr = std::current_exception())
{
if (!eptr) { throw std::bad_exception(); }

std::string whaaat;
std::size_t num_nested = 0;
next:
{
try
{
std::exception_ptr yeptr;
std::swap(eptr, yeptr);
std::rethrow_exception(yeptr);
}
catch (const std::exception &e) { whaaat += e.what() ; eptr = get_nested(e); }
catch (const std::string &e) { whaaat += e ; }
catch (const char *e) { whaaat += e ; }
catch (...) { whaaat += "who knows"; }

if (eptr) { whaaat += " ("; num_nested++; goto next; }
}
whaaat += std::string(num_nested, ')');
return whaaat;
}

同样的:

Here is WHAT happened: "success!"
here is what: "run() failed (Couldn't open nonexistent.file (basic_ios::clear))"

http://coliru.stacked-crooked.com/a/32ec5af5b1d43453

UPD

可以在 C++03 中通过使用允许在 catch block 之外重新throw 当前异常的技巧来实现类似的功能:https://stackoverflow.com/a/3641809/5447906

关于c++ - 如何调用 std::exception_ptr 上的 what(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14232814/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com