如何正确使用BOOST_THROW_EXCEPTION?

How to use BOOST_THROW_EXCEPTION correctly?

提问人:AeroSun 提问时间:2/2/2018 最后编辑:milbrandtAeroSun 更新时间:3/17/2022 访问量:1908

问:

我尝试使用提升异常并下降。 有问题代码:

struct exception_base : virtual std::exception, virtual boost::exception 
{
    exception_base(std::exception&& e)
        : std::exception(e)
    {}
};

int main()
{
    std::string exception_description;

    try
    {
        BOOST_THROW_EXCEPTION(exception_base(std::runtime_error("hello exception")));
    }
    catch (exception_base& ex)
    {
        exception_description = boost::diagnostic_information(ex);
    }

    return 0;
}

在这种情况下,exception_description的值具有最后一个字符串 - “std::exception::what: Unknown exception”。这是意想不到的价值。如果我将BOOST_THROW_EXCEPTION更改为通常的抛出 - exception_description值的最后一个字符串看起来是预期的 - “std::exception::what: hello exception"

那么如何正确使用BOOST_THROW_EXCEPTION呢?

C++ C++11 提升异常

评论


答:

2赞 John Zwinck 2/2/2018 #1

自定义异常类不是必需的,并且是问题的根本原因。如果你删除它,你可以这样做:

BOOST_THROW_EXCEPTION(std::runtime_error("hello exception"));

然后:

catch (const std::exception& ex)

代码将按照您期望的方式工作。

为什么它以前不起作用?好吧,你的类没有存储错误消息,所以当你从 a 构造它时,它不能存储消息(例如,从 原始 )。exception_basestd::exceptionruntime_error

你可以用很多不同的方法修复它,但最终它们会归结为同一件事:如果你希望你的自定义异常类包含一个消息字符串,它必须以某种方式包含该消息字符串。

我喜欢在 95% 的时间内不定义自定义异常类型,所以我建议您保持简单并使用(和/或)。runtime_errorlogic_error

请注意,它会自动添加为抛出类型的基类,因此您无论如何都不需要自己这样做 - 没有任何优势。BOOST_THROW_EXCEPTIONboost::exception


其他事项:

  • 在您的捕获站点使用,这将打印所有添加的元数据,例如:文件、行、函数等std::cerr << boost::diagnostic_information(ex) << std::endl;BOOST_THROW_EXCEPTION
  • 如果你抛出一个内部,你可以将你的 替换为 将类型更改为 ,这允许您通过std::exceptionBOOST_THROW_EXCEPTION()std::exceptionboost::enable_error_info()boost::exceptionoperator<<

评论

0赞 AeroSun 2/2/2018
嗨,约翰,你不明白我的意思。这是描述麻烦的最简单的代码。我需要额外的提升异常未来作为行号、函数名称、出现异常的文件名。因此,我需要按照boost文档中描述的方式使用类exception_base。此外,对于升价期货,我需要使用BOOST_THROW_EXCEPTION而不是普通抛出关键字。
0赞 John Zwinck 2/2/2018
如果你尝试我建议的代码,你会发现它确实支持抛出异常的行号、函数名和文件名。所有这些都是由 自动完成的。试试吧!BOOST_THROW_EXCEPTION
0赞 AeroSun 2/2/2018
我明白了。您的代码只需要一些修复 - catch 中必须有 boost::exception 而不是 std::exception。使用 std::exception 它不适用于我这边,但使用 boost 它可以工作。但!如果我需要自定义例外 - 我能做什么?
0赞 AeroSun 2/2/2018
我也不明白你关于“类没有错误消息存储”的观点 - 为什么?它派生自 std::exception - 因此它具有 std::exception 的所有功能
0赞 John Zwinck 2/2/2018
如果你绝对必须有一个自定义的异常类,那么你需要正确地实现它,将消息存储在里面。为此,你可以从类中派生或在类中添加一个,并将消息存储在该类中。 它里面没有错误消息 - 你可以通过观察它没有接受字符串的构造函数来知道这一点。runtime_errorstd::stringstd::exception