如何使用boost异常向std :: exception添加信息

时间:2014-09-10 07:08:41

标签: c++ exception boost

Boost Exception框架非常棒。您可以在应用程序的相应级别向std::exceptionboost::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")); 
}

是否可以保留原始异常及其位置等,并且以后仍能够添加更多信息?怎么样?

2 个答案:

答案 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::exceptionstd::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