C++ 我可以用错误信息复制boost::exception吗?
考虑以下使用boost异常类的代码:C++ 我可以用错误信息复制boost::exception吗?,c++,exception,boost,boost-exception,C++,Exception,Boost,Boost Exception,考虑以下使用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)
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";}
};
并使用它们:
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) );
}
这确实表明,当我将Exc
对象复制到exception\u impl
基类对象中时,信息丢失了:
========================================================================
exc:
Throw location unknown (consider using BOOST_THROW_EXCEPTION)
Dynamic exception type: some_exception
[tag_test_int*] = 42
========================================================================
*this:
Throw location unknown (consider using BOOST_THROW_EXCEPTION)
Dynamic exception type: exception_impl
std::exception::what: "blah"
========================================================================
执行委员会:
抛出位置未知(考虑使用BOOST\u抛出异常)
动态异常类型:某些\u异常
[tag_test_int*]=42
========================================================================
*这:
抛出位置未知(考虑使用BOOST\u抛出异常)
动态异常类型:异常\u impl
std::异常::什么:“废话”
根据标准,异常对象必须是可复制的,并且不管可能的优化,抛出表达式的结果都会被复制。因此boost的异常必须是可复制的,并且它们肯定不会在过程中丢失信息。我一定错过了一些很明显的东西
我做错了什么 对我来说非常好:
(我必须在exception_impl中添加一个默认构造函数) 使用以下方式编译:
- g++(Ubuntu 4.9.2-0ubuntu1~14.04)4.9.2
- 增加1.55
我认为问题在于您在构造函数中输出诊断信息,而tag_test_int未设置为jet。可能相关且正常,因此出于某种无法解释的原因(无论如何,我无法解释),当我从
boost::exception
非虚拟地派生exception
时,问题就消失了。我很困惑,希望听到一个解释。@sehe:我浏览了文件,但没有看到任何相关内容。你在暗示什么?看起来克隆显然不是一项功能,原因是(例如,“因为克隆功能只是0x”[…]”之前的权宜之计,没有-但是异常(仅)将得到一个特殊的内置克隆机制(n2179)”)暗示它是通过其他方式解决的。再读一遍,可能会涉及到boost::copy\u异常(另请参见)您能提供MCVE吗?这个问题很难理解,所以我回家了,但这个问题的时间到了。因此,我不会浪费一半的赏金,而是给了这个答案,因为这是我唯一得到的答案。当我找到工作时间时,我会去看看代码,并试图找出我的代码与你的代码有什么不同。感谢你和所有调查此事的人!我终于花时间找到了这个。在coliru上按预期工作,但在我的平台上不工作。我情不自禁地认为这是因为我们一直在使用Boost1.52,它应该有一个bug。(我们也在使用一个较旧的编译器,但我怀疑这会导致这样的错误。)由于我们无能为力,我们暂时只能非虚拟地派生。再次感谢您的努力!我在我的开发系统上安装了Boost1.48,它的工作原理与cliru类似。所以也许你得看看你的编译器,我的是gcc版本4.6.3(Ubuntu/Linaro 4.6.3-1ubuntu5)。
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:
Throw location unknown (consider using BOOST_THROW_EXCEPTION)
Dynamic exception type: some_exception
[tag_test_int*] = 42
========================================================================
*this:
Throw location unknown (consider using BOOST_THROW_EXCEPTION)
Dynamic exception type: exception_impl
std::exception::what: "blah"
#include <iostream>
#include <exception>
#include <boost/exception/all.hpp>
using std::cout;
class myException : public virtual boost::exception {
};
template <class T>
class exception_impl : public virtual std::exception, public T {
public:
exception_impl() {}
exception_impl(const T& ex) : T(ex) {}
virtual const char* what() const throw() {return "blah";}
};
class some_exception : public myException {
};
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) );
}
int main() {
try {
f();
} catch (boost::exception& e) {
cout << boost::diagnostic_information(e);
}
return 0;
}
Throw location unknown (consider using BOOST_THROW_EXCEPTION)
Dynamic exception type: N5boost16exception_detail10clone_implI14exception_implI14some_exceptionEEE
std::exception::what: blah
[P12tag_test_int] = 42