如何正确使用BOOST_THROW_EXCEPTION?
How to use BOOST_THROW_EXCEPTION correctly?
我尝试使用 boost 异常并失败。
有问题代码:
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呢?
您的自定义异常 class 不是必需的,它是您出现问题的根本原因。如果你删除它,你可以这样做:
BOOST_THROW_EXCEPTION(std::runtime_error("hello exception"));
然后:
catch (const std::exception& ex)
并且代码将按您期望的方式工作。
为什么以前没有用?好吧,您的 exception_base
class 没有存储错误消息,因此当您从 std::exception
构建它时,它无法存储消息(例如来自原始 runtime_error
)。
你可以用很多不同的方法来修复它,但最终它们会归结为同一件事:如果你想让你的自定义异常 class 包含一个消息字符串,它必须以某种方式包含该消息字符串.
我喜欢在 95% 的情况下不定义自定义异常类型,所以我建议您保持简单并使用 runtime_error
(and/or logic_error
).
请注意,BOOST_THROW_EXCEPTION
会自动添加 boost::exception
作为抛出类型的基础 class,因此您无论如何都不需要自己这样做——没有任何优势。
其他:
- 在您的 catch 站点使用
std::cerr << boost::diagnostic_information(ex) << std::endl;
,这将打印 BOOST_THROW_EXCEPTION
添加的所有元数据,例如:文件、行、函数等
- 如果你在
BOOST_THROW_EXCEPTION()
中放置一个 std::exception
你可以用 boost::enable_error_info()
包装你的 std::exception
来改变类型为 boost::exception
然后允许您通过 operator<<
使用其他任意字段丰富异常
我尝试使用 boost 异常并失败。 有问题代码:
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呢?
您的自定义异常 class 不是必需的,它是您出现问题的根本原因。如果你删除它,你可以这样做:
BOOST_THROW_EXCEPTION(std::runtime_error("hello exception"));
然后:
catch (const std::exception& ex)
并且代码将按您期望的方式工作。
为什么以前没有用?好吧,您的 exception_base
class 没有存储错误消息,因此当您从 std::exception
构建它时,它无法存储消息(例如来自原始 runtime_error
)。
你可以用很多不同的方法来修复它,但最终它们会归结为同一件事:如果你想让你的自定义异常 class 包含一个消息字符串,它必须以某种方式包含该消息字符串.
我喜欢在 95% 的情况下不定义自定义异常类型,所以我建议您保持简单并使用 runtime_error
(and/or logic_error
).
请注意,BOOST_THROW_EXCEPTION
会自动添加 boost::exception
作为抛出类型的基础 class,因此您无论如何都不需要自己这样做——没有任何优势。
其他:
- 在您的 catch 站点使用
std::cerr << boost::diagnostic_information(ex) << std::endl;
,这将打印BOOST_THROW_EXCEPTION
添加的所有元数据,例如:文件、行、函数等 - 如果你在
BOOST_THROW_EXCEPTION()
中放置一个std::exception
你可以用boost::enable_error_info()
包装你的std::exception
来改变类型为boost::exception
然后允许您通过operator<<
使用其他任意字段丰富异常