Boost Exception框架非常棒。您可以在应用程序的相应级别向std::exception
和boost::exception
派生的异常添加信息,如in the documentation所述。
但是,如果您不控制代码中的throw网站,如何添加此类信息,例如std lib引发异常,例如地图抛出out_of_range?
它不能被捕获为boost :: exception,因为它不是从它派生的:
try {
my_map.at(id);
} catch(boost::exception &e) { // NOT caught
e << errinfo_desc("id not found, map out of range");
throw;
}
它可以作为std :: exception捕获,因为out_of_range派生自std :: exception,但是可以添加 no 信息,因为它不是boost::exception
:
try {
my_map.at(id);
} catch(std::exception &e) {
// compile error: e << errinfo_desc("id not found, map out of range");
throw;
}
抓取std::exception
并投掷新的boost::exception
会丢失异常的原始位置,这是不希望的:
try {
my_map.at(id);
} catch(std::exception &e) {
BOOST_THROW_EXCEPTION(my_exception()
<< errinfo_desc("id not found, map out of range"));
}
是否可以保留原始异常及其位置等,并且以后仍能够添加更多信息?怎么样?
答案 0 :(得分:0)
就个人而言,我尽可能使用std::exception
层次结构。当它们不够时,我只是从std::exception
派生我的异常类。从来没有boost::exception
的任何用例(也许我的所有代码都太简单了,不知道)。
但是如果你真的想要将两者结合起来,这是一个疯狂的想法:使用多重继承。代码草图(未经测试,更像伪代码):
// two personalities in one exception object
class MyException: public std::exception, public boost::exception {
explicit MyException(const std::exception& stdex) { ... }
... other ctors as needed...
... other stuff ...
};
...
try {
my_map.at(id);
} catch (const std::exception& stdex) {
MyException myex(stdex); // gets SOME of the std::exception information
myex << errinfo_desc("id not found, map out of range"); // boost::exception goodies
throw myex;
}
明显需要注意:使用std :: exception引用初始化MyException对象时会出现问题。而MI的常见问题。你被警告: - )
答案 1 :(得分:0)
您可以通过捕获这两种情况来执行此操作:boost::exception
和std::exception
try {
my_map.at(id);
} catch(boost::exception &e) {
// If already a boost exception, catch here and add information
e << errinfo_desc("id not found, map out of range");
throw;
} catch(std::exception &) {
// Otherwise, catch here and convert to a boost exception
try { boost::rethrow_exception( boost::current_exception() ); }
catch( boost::exception& e ) {
e << errinfo_desc("id not found, map out of range");
throw;
}
}
如果发现编写那么多代码很痛苦,那么我问是否有更简洁的方法:Adding error_info to std::exception