添加到ERROR_INFO标准::异常 [英] Adding error_info to std::exception
问题描述
我整合的boost ::例外
到现有code。一些code的现在使用 BOOST_THROW_EXCEPTION
,但有些人可能还是抛出标准的的std ::例外
。
I'm integrating boost::exception
into existing code. Some of the code now uses BOOST_THROW_EXCEPTION
, but some might still throw standard std::exception
.
我想在中间抓站点添加ERROR_INFO。根据文档,如果异常是的boost ::例外
,我可以做到这一点:
I want to add error_info at an intermediary catch site. According to the docs, if the exception is a boost::exception
, I can just do this:
try {
do_something()
}
catch( boost::exception & e ) {
e << boost::errinfo_file_name(file_name);
throw;
}
但是,这将仅在信息添加到升压异常。我想将它添加到的std ::例外
为好。什么是做到这一点的干净的方式?这里有一种方法,但它会导致一些code复制:
But that will only add the info to the boost exceptions. I want to add it to the std::exception
as well. What's the cleanest way to do that? Here's one way, but it results in some code duplication:
try {
do_something()
}
catch( boost::exception & e ) {
e << boost::errinfo_file_name(file_name);
throw;
}
catch( std::exception & e ) {
throw enable_error_info(e) << boost::errinfo_file_name(file_name);
}
有没有这相当于一个方法,给我当前异常作为升压异常,或者创建一个升压例外出来,如果它不是一?
Is there a method that's equivalent to "give me the current exception as a boost exception, or create a boost exception out of it if it isn't one"?
修改:的boost :: enable_error_info()
确实有点那个,但返回原始异常的副本,其中切片脱的boost ::例外
我捕捉异常的一部分。案例分析:</ P>
EDIT: boost::enable_error_info()
kinda does that but returns a copy of the original exception, which slices off the boost::exception
part of the exception I'm catching. Case in point:
int main()
{
try {
try {
BOOST_THROW_EXCEPTION( std::runtime_error( "foo" ) );
}
catch( std::exception & e ) {
std::cerr << e.what() << std::endl; // "foo"
if( const char* const* function = boost::get_error_info<boost::throw_function>(e) ) std::cerr << *function << std::endl; // "int main()"
throw boost::enable_error_info(e) << boost::errinfo_file_name("bar");
}
}
catch( std::exception & e ) {
std::cerr << e.what() << std::endl; // "std::exception"
if( const char* const* function = boost::get_error_info<boost::throw_function>(e) ) std::cerr << *function << std::endl; // NOTHING
}
return 0;
}
修改:我尝试使用的boost :: current_exception()
,它太切片东西了。基本上,任何试图复制一个异常会松一些,因为造成的多重继承切片的数据。同样的原因,为什么文档说,你应该总是重新抛出使用扔
而不是抛电子商务
。所以,我的真正的不想承担任何复制,除非它是必要的。
EDIT: I tried using boost::current_exception()
, and it slices things off too. Basically, any attempt to copy an exception will loose some of the data because of the slicing caused by multiple inheritance. Same reason as why the docs say you should always rethrow using throw
instead of throw e
. So I really don't want to incur any copying unless it's necessary.
在理想情况下,我想写出以下内容,其中 current_exception_as_boost_exception()
返回参照当前异常,如果它已经是一个提振::例外
,否则返回调用的boost :: enable_error_info
上的结果。
Ideally, I'd like to write the following, where current_exception_as_boost_exception()
returns a reference to the current exception if it is already a boost::exception
, otherwise returns the result of calling boost::enable_error_info
on it.
try {
do_something()
}
catch( std::exception & e ) {
throw current_exception_as_boost_exception() << boost::errinfo_file_name(file_name);
}
难道这就是提振::函数enable_current_exception
是?这真的不清楚它的目的是什么,它不是在任何教程使用。
Is that what boost::enable_current_exception
is for? It's really unclear what its purpose is, and it's not used in any of the tutorials.
推荐答案
下面是一个解决方案,我想要做什么。但是,如果感觉就像我在这里彻底改造的东西。是不是有一个内置的方式来达到同样的事情?
Here is a solution that does what I want. But if feels like I'm reinventing something here. Isn't there a built-in way to achieve the same thing?
struct rethrow
{
rethrow()
{
try{ throw; }
// Already a boost::exception
catch( boost::exception& ) {}
// Something else. Make it a boost::exception
catch( ... ) { ptr = boost::current_exception(); }
}
template<class T>
rethrow const& operator<<( const T& t ) const
{
try
{
re();
}
catch( boost::exception& e )
{
e << t;
}
return *this;
}
~rethrow()
{
re();
}
private:
void re() const
{
if( !ptr ) throw;
else boost::rethrow_exception( ptr );
}
boost::exception_ptr ptr;
};
int main()
{
try {
try {
throw std::runtime_error( "foo" ); // or BOOST_THROW_EXCEPTION( std::runtime_error( "foo" ) );
}
catch( std::exception & e ) {
rethrow() << boost::errinfo_file_name("bar");
}
}
catch( std::exception & e ) {
std::cerr << __LINE__ << ": caught " << e.what() << std::endl; // "caught foo"
if( const char* const* function = boost::get_error_info<boost::throw_function>(e) ) std::cerr << __LINE__ << ": throw from " << *function << std::endl; // "throw from int main()" (when using BOOST_THROW_EXCEPTION)
if( std::string const* fileName = boost::get_error_info<boost::errinfo_file_name>(e) ) std::cerr << __LINE__ << ": trying to open " << *fileName << std::endl; // "trying to open bar"
}
return 0;
}
这篇关于添加到ERROR_INFO标准::异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!