• 16.3. Boost.NumericConversion

    16.3. Boost.NumericConversion

    Boost.NumericConversion 可将一种数值类型转换为不同的数值类型。 在C++里, 这种转换可以隐式地发生,如下面例所示。

    1. #include <iostream>
    2.  
    3. int main()
    4. {
    5. int i = 0x10000;
    6. short s = i;
    7. std::cout << s << std::endl;
    8. }
    • 下载源代码

    由于从 intshort 的类型转换自动产生,所以本例编译没有错误。 虽然本例可以运行,但结果由于依赖具体的编译器实现而结果无法预期。 数字0x10000对于变量 i 来说太大而不能存储在 short 类型的变量中。 依据C++标准,这个操作的结果是实现定义的("implementation defined")。 用Visual C++ 2008编译,应用程序显示的是0s 的值当然不同于 i 的值。

    为避免这种数值转换错误,可以使用 boost::numeric_cast 类型转换操作符。

    1. #include <boost/numeric/conversion/cast.hpp>
    2. #include <iostream>
    3.  
    4. int main()
    5. {
    6. try
    7. {
    8. int i = 0x10000;
    9. short s = boost::numeric_cast<short>(i);
    10. std::cout << s << std::endl;
    11. }
    12. catch (boost::numeric::bad_numeric_cast &e)
    13. {
    14. std::cerr << e.what() << std::endl;
    15. }
    16. }
    • 下载源代码

    boost::numeric_cast 的用法与C++类型转换操作符非常相似。 当然需要包含正确的头文件;就是 boost/numeric/conversion/cast.hpp

    boost::numeric_cast 执行与C++相同的隐式转换操作。 但是,boost::numeric_cast 验证了在不改变数值的情况下转换是否能够发生。 前面给的应用例子,转换不能发生,因而由于0x10000太大而不能存储在 short 类型的变量上,而抛出 boost::numeric::bad_numeric_cast 异常。

    严格来讲,抛出的是 boost::numeric::positive_overflow 类型的异常,这个类型特指所谓的溢出(overflow) - 在此例中是正数。 相应地,还存在着 boost::numeric::negative_overflow 类型的异常,它特指负数的溢出。

    1. #include <boost/numeric/conversion/cast.hpp>
    2. #include <iostream>
    3.  
    4. int main()
    5. {
    6. try
    7. {
    8. int i = -0x10000;
    9. short s = boost::numeric_cast<short>(i);
    10. std::cout << s << std::endl;
    11. }
    12. catch (boost::numeric::negative_overflow &e)
    13. {
    14. std::cerr << e.what() << std::endl;
    15. }
    16. }
    • 下载源代码

    Boost.NumericConversion 还定义了其他的异常类型,都继承自 boost::numeric::bad_numeric_cast。 因为 boost::numeric::bad_numeric_cast 继承自 std::bad_cast,所以 catch 处理也可以捕获这个类型的异常。