捕获加速异常并提取其消息

Catching a Boost exception and extracting its message

本文关键字:提取 消息 异常 加速      更新时间:2023-10-16

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

如果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 是抽象的。

(我去过许多网站和页面,包括这个标题相似但充满了插入函数调用的"<<"运算符,像boost::get_error_info<my_tag_error_info>(e)这样的模板结构,通常比我怀疑的要复杂得多。 我只需要上述工作。

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

当你按值捕获boost::exception时,就像你所做的那样,编译器必须在你的 catch 块中制作它的本地副本;它没有足够的信息来做!

在特定情况下,最佳解决方案是捕获对原始异常的引用。

关于从 Boost.format 捕获异常,它会抛出派生自 boost::io::format_error 的异常, 派生自 std::exception ,而不是 boost::exception 。你应该抓住boost::io::format_error.