4.9.6 使用函数抛出异常
exception库为异常增加了许多新的功能,带来了很多好处,但由于这样那样的原因,程序中的异常类并不能总是从boost::exception继承,必须使用enable_error_info()来包装。
exception库提供throw_exception()函数来简化enable_error_info()的调用,它可以代替原始的throw语句来抛出异常,会自动使用enable_error_info()来包装异常对象,而且支持线程安全,比直接使用throw更好,相当于:
- throw (boost::enable_error_info(e))
从而确保抛出的异常是boost::exception的子类,可以追加异常信息。例如:- throw_exception(std::runtime_error("runtime"));
在throw_exception()的基础上exception库又提供了一个非常有用的宏BOOST_ THROW_EXCEPTION,它调用了boost::throw_exception()和enable_error_info(),因而可以接受任意的异常类型,同时又使用throw_function、throw_file和throw_line自动向异常添加了发生异常的函数名、文件名和行号等信息。
但需要注意一点,为了保证与配置宏BOOST_NO_EXCEPTIONS兼容(这个宏本书不做介绍),throw_exception()函数和BOOST_THROW_EXCEPTION宏都要求参数e必须是std:: exception的子类。
对于新写的异常类来说这通常不是问题,因为它们总是从std::exception和boost:: exception继承,但假如旧代码中有非std::exception的派生异常就无法使用,这在一定程度上限制了throw_exception()和BOOST_NO_EXCEPTIONS的应用范围。
如果确保在程序中总使用boost::exception,不会去定义配置宏BOOST_NO_EXCEPTIONS(这应该是大多数情况),那么可以修改Boost源代码,在<boost/throw_exception.hpp>里注释掉throw_exception_assert_compatibility(e)这条语句,以取消这个限制。
throw_exception()和BOOST_THROW_EXCEPTION的示范代码请参见4.9.7节。