考虑以下示例(取自https://theboostcpplibraries.com/boost.exception)
#include <boost/exception/all.hpp>
#include <exception>
#include <new>
#include <string>
#include <algorithm>
#include <limits>
#include <iostream>
typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info;
struct allocation_failed : public std::exception
{
const char *what() const noexcept { return "allocation failed"; }
};
char *allocate_memory(std::size_t size)
{
char *c = new (std::nothrow) char[size];
if (!c)
BOOST_THROW_EXCEPTION(allocation_failed{});
return c;
}
char *write_lots_of_zeros()
{
try
{
char *c = allocate_memory(std::numeric_limits<std::size_t>::max());
std::fill_n(c, std::numeric_limits<std::size_t>::max(), 0);
return c;
}
catch (boost::exception &e)
{
e << errmsg_info{"writing lots of zeros failed"};
throw;
}
}
int main()
{
try
{
char *c = write_lots_of_zeros();
delete[] c;
}
catch (boost::exception &e)
{
std::cerr << *boost::get_error_info<errmsg_info>(e);
}
}
函数allocate_memory()
使用以下语句抛出异常
BOOST_THROW_EXCEPTION(allocation_failed{});
在catch块中如何将boost::exception &e
转换回allocation_failed
?
另外,如果我的代码有多个throw语句,如BOOST_THROW_EXCEPTION(A{})
,BOOST_THROW_EXCEPTION(B{})
,BOOST_THROW_EXCEPTION(C{})
等,其中A,B,C是类。在不使用boost的情况下,我可以按以下方式为每种类型的异常设置单独的catch块。
...
catch(A e){
...
}
catch(B e){
...
}
catch(C e){
...
}
如何在使用提升时执行相同操作,以便BOOST_THROW_EXCEPTION(A{})
,BOOST_THROW_EXCEPTION(B{})
,BOOST_THROW_EXCEPTION(C{})
等转到不同的catch块?
我是新手来推动图书馆,其中一些概念让我望而却步。
答案 0 :(得分:2)
BOOST_THROW_EXCEPTION
之外, boost::exception
总是抛出一个继承其参数类型的类型。这意味着两件事:
dynamic_cast
从boost::exception
到传递的类型。-
catch (boost::exception &e)
{
std::cerr << *boost::get_error_info<errmsg_info>(e);
if ( allocation_failed* af = dynamic_cast<allocation_failed*>(&e) )
{
std::cerr << af->what() << std::endl; // redundant
}
}
-
catch (A& a) {
// ...
} catch (B& b) {
// ...
} catch (C& c) {
// ...
}
当然,这样做,如果您想要任何提升错误格式或额外数据,则需要dynamic_cast
将异常对象boost::exception*
。