【发布时间】:2015-06-22 18:55:39
【问题描述】:
考虑以下使用 boost 异常类的代码:
class exception : virtual public boost::exception {
// ...
};
template<typename Exc>
class exception_impl : virtual public std::exception
, public Exc {
public:
exception_impl(const Exc& exc) : Exc(exc) {}
virtual const char* what() const throw() {return "blah";}
};
(实际上这段代码更复杂。例如,exception_impl 仅派生自 std::exception,如果后者还不是 Exc 的直接或间接基类。但这只是分散了我对问题的注意力有,所以我跳过了。)
鉴于此,我现在可以派生我自己的异常类:
class some_exception : public exception {
// ...
};
并使用它们:
struct tag_test_int;
typedef boost::error_info<tag_test_int,int> test_int_info;
void f()
{
boost::throw_exception( exception_impl<some_exception>() << test_int_info(42) );
}
但是,结果表明生成的异常没有test_int_info 对象。所以我更改了exception_impl 构造函数以提供一些诊断信息:
exception_impl(const Exc& exc)
: Exc(exc) {
std::cerr << "========================================================================\nexc:\n";
std::cerr << boost::diagnostic_information(exc);
std::cerr << "========================================================================\n*this:\n";
std::cerr << boost::diagnostic_information(*this);
std::cerr << "========================================================================\n";
}
这确实表明当我将Exc 对象复制到exception_impl 基类对象中时信息丢失了:
IIRC,异常对象必须根据标准是可复制的,并且忽略可能的优化,将复制 throw 表达式的结果。所以 boost 的异常必须是可复制的,并且它们当然不会在此过程中丢失信息。我必须在这里遗漏一些相当明显的东西。
我做错了什么?
【问题讨论】:
-
好的,所以由于一些莫名其妙的原因(无论如何我都莫名其妙),当我导出
exception非虚拟时问题就消失了来自boost::exception。我很困惑,很想听听解释。 -
@sehe:我浏览了这些文件,但没有看到任何相关内容。你在暗示什么?
-
看起来克隆显然不是一项功能,并说明原因(例如“由于克隆功能只是 0x 之前的权宜之计”[...]“否 - 但异常(仅)将获得特殊的内置克隆机制 (n2179)”here) 暗示它已通过其他方式解决。再读一遍,看起来
boost::copy_exception可能参与其中(另见Luc's answer) -
你能提供一个 MCVE 吗?这个问题很难理解。
标签: c++ exception boost boost-exception