我正在编写一个函数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,其标题相似但是充满了'&lt;&lt;'运算符插入到函数调用中,模板结构如{{1而且通常比我怀疑的更复杂。我只需要上面的工作。)
答案 0 :(得分:0)
您不能拥有抽象类型的自动变量。但是,您可以有一个引用或指针。这样做的原因是编译器无法确切知道变量实际上是哪个派生类型,因此它不知道要为它分配多少空间或者要使用哪个类的复制构造函数。
当您按照值捕获boost::exception
时,编译器必须在catch块中创建它的本地副本;它没有足够的信息可以做!
在您的具体情况下,最佳解决方案是捕获对原始异常的引用。
关于从Boost.Format中捕获异常,它会抛出派生自boost::io::format_error
的异常,这些异常派生自std::exception
,而不是boost::exception
。你应该抓住boost::io::format_error
。