![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Improved numeric_cast<>Boost , Chapter 1. Boost.NumericConversion , Chapter 1. Boost.NumericConversion
Отсутствие сохранения диапазона делает конверсии между числовыми типами склонными к ошибкам. Это верно как для неявных, так и для явных конверсий (через Существует несколько ситуаций, когда конверсия небезопасна:
C++ Стандарт не определяет поведение, когда числовому типу присваивается значение, которое не может быть представлено типом, за исключением неподписанных интегральных типов [3.9.1.4], которые должны подчиняться законам арифметического модуля 2n (это подразумевает, что в результате будет уменьшено модульное число, которое на одно больше самого большого значения, которое может быть представлено). Тот факт, что поведение переполнения не определено для всех конверсий (за исключением вышеупомянутых неподписанных), делает любой код, который может привести к положительным или отрицательным переполнениям, подверженным проблемам переносимости. По умолчанию template <typename Target, typename Source> inline Target numeric_cast( Source arg ) { typedef conversion_traits<Target, Source> conv_traits; typedef numeric_cast_traits<Target, Source> cast_traits; typedef converter < Target, Source, conv_traits, typename cast_traits::overflow_policy, typename cast_traits::rounding_policy, raw_converter<conv_traits>, typename cast_traits::range_checking_policy > converter; return converter::convert(arg); }
template <typename Target, typename Source, typename EnableIf = void> struct numeric_cast_traits { typedef def_overflow_handler overflow_policy; typedef UseInternalRangeChecker range_checking_policy; typedef Trunc<Source> rounding_policy; }; Поведение Следующий пример выполняет некоторые типичные преобразования между числовыми типами:
int main() { using boost::numeric_cast; using boost::numeric::bad_numeric_cast; using boost::numeric::positive_overflow; using boost::numeric::negative_overflow; try { int i=42; short s=numeric_cast<short>(i); // This conversion succeeds (is in range) } catch(negative_overflow& e) { std::cout << e.what(); } catch(positive_overflow& e) { std::cout << e.what(); } try { float f=-42.1234; // This will cause a boost::numeric::negative_overflow exception to be thrown unsigned int i=numeric_cast<unsigned int>(f); } catch(bad_numeric_cast& e) { std::cout << e.what(); } double d= f + numeric_cast<double>(123); // int -> double unsigned long l=std::numeric_limits<unsigned long>::max(); try { // This will cause a boost::numeric::positive_overflow exception to be thrown // NOTE: *operations* on unsigned integral types cannot cause overflow // but *conversions* to a signed type ARE range checked by numeric_cast. unsigned char c=numeric_cast<unsigned char>(l); } catch(positive_overflow& e) { std::cout << e.what(); } return 0; } Статья Improved numeric_cast<> раздела Chapter 1. Boost.NumericConversion Chapter 1. Boost.NumericConversion может быть полезна для разработчиков на c++ и boost. Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта. :: Главная :: Chapter 1. Boost.NumericConversion ::
|
||||||||||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |