【问题标题】:Catching a Boost exception and extracting its message捕获 Boost 异常并提取其消息
【发布时间】:2014-02-26 02:46:38
【问题描述】:

我正在编写一个函数wd_sprintf,以提供类似 sprintf 的 API。在幕后,它使用了 boost 库。

如果wd_sprintf的用户对格式字符串编码不正确,boost::format会抛出异常。我想让我的函数拦截异常,将其重新打包到一条消息中,将wd_sprintf 标识为错误的位置,然后重新抛出异常。

我不知道要捕获什么,以及如何提取消息。

// wd_sprintf(pattern [,args...]):                                                                                                                                              
//                                                                                                                                                                              
// This creates a temporary boost::format from pattern, and calls                                                                                                               
// wd_sprintf_r() to recursively extract and apply arguments.                                                                                                                   
#include <boost/exception/all.hpp>
class wd_sprintf_exception : std::runtime_error {
public:
    wd_sprintf_exception(string const& msg : std::runtime_error(msg) {}
};

template <typename... Params>
string
wd_sprintf (const string &pat, const Params&... parameters) {
    try {
        boost::format boost_format(pat);
        return wd_sprintf_r(boost_format, parameters...);
    }
    catch (boost::exception e) {
        const string what = string("wd_sprintf: ") + string(e.what());
        throw wd_sprintf_exception(what);
    }
}

当然,这会产生编译错误,因为 boost::exception 是抽象的。

(我去过很多网站和页面,包括this one,其标题相似,但充满了插入函数调用的“boost::get_error_info<my_tag_error_info>(e) 之类的模板结构,以及通常很多比我想象的更复杂。我只需要上面的工作。)

【问题讨论】:

  • 你应该永远是catching by referenceboost::exception(和 C++ 标准库)就是这样设计的。

标签: c++ exception boost try-catch


【解决方案1】:

您不能拥有抽象类型的自动变量。但是,您可以拥有一个引用或指针。这样做的原因是编译器无法确切知道变量实际上是哪个派生类型,因此它不知道为其分配多少空间或使用哪个类的复制构造函数。

当您按值捕获boost::exception 时,编译器必须在您的catch 块中制作它的本地副本;它没有足够的信息去做!

在您的具体情况下,最好的解决方案是捕获对原始异常的引用。

关于从 Boost.Format 中捕获异常,它会抛出派生自 boost::io::format_error 的异常,后者派生自 std::exception,而不是 boost::exception。你应该正在赶上boost::io::format_error

【讨论】:

  • 这很有帮助,并且通过引用捕获消除了编译器错误。但我仍然不知道如何从 e 中提取消息。 (e.what() 不起作用,因为 boost::exception 没有 what()
  • 仍然不能正常工作。我现在已将其更改为 catch (boost::io::format_error&amp; e) {,其他所有内容都相同,包括 throw wd_sprintf_exception(what);wd_sprintf_exception 派生自 std::runtime_error。)客户使用 try { ... } catch (std::runtime_error&amp; e) { cout &lt;&lt; e.what() &lt;&lt; endl;} 包装他对 wd_sprintf 的调用.异常没有被捕获;相反,我中止了 wd_sprintf_exception 类型的未捕获异常。
  • 但是,如果 -- 而不是throw wd_sprintf_exception(what); -- 我只是写throw;,我的未捕获异常消息会显示以 boost::exception_detail::clone_impl 类型的未捕获异常终止::exception_detail::error_info_injector<:io::bad_format_string> >: boost::bad_format_string: format-string is ill-formed,这至少是我想要的文本!
猜你喜欢
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-04
  • 1970-01-01
  • 2010-11-01
相关资源
最近更新 更多