2010-01-03 2 views
4

Всякий раз, когда преобразование boost numeric_cast<> не выполняется, оно генерирует исключение. Есть ли подобный шаблон в boost, который позволяет мне указывать значение по умолчанию вместо этого, или вы ловите исключение, единственное, что я могу сделать в этом случае?Boost numeric_cast <> со значением по умолчанию вместо исключения?

Я не слишком беспокоюсь о производительности всей дополнительной обработки исключений, но я бы предпочел использовать стандартный шаблон, чем писать бесполезные функции обертки. Кроме того, из прошлого опыта, я думал, что, вероятно, что у boost действительно есть то, о чем я думаю, и я просто его не нашел.

+0

Дело в том, что оно * делает * исключение. Если вы этого не хотите, просто бросьте. –

+0

nobugs: numeric \ _cast обнаруживает переполнение и нижнее течение, тогда как «просто кастинг» не будет. – 2010-01-03 00:39:30

ответ

6

numeric_cast функция просто вызывает класс boost::numeric::converter шаблона с аргументами по умолчанию. Один из аргументов - OverflowHandler, а значение по умолчанию для этого - def_overflow_handler, но вы можете указать silent_overflow_handler для исключения исключения.

Затем укажите аргумент FloatToIntRounder, который предоставит желаемое значение по умолчанию, если входной аргумент находится за пределами желаемого диапазона. Аргумент обычно используется для обеспечения целого числа для округления с использованием типа с плавающей точкой, но вы действительно можете использовать его для всех, что хотите. Дополнительная информация, плюс код, описывающий последовательность событий, на converter documentation.

Насколько я знаю, Boost не имеет того, о чем вы думаете, но оно предоставляет вам возможность самостоятельно построить его.

3

Это неоднократно обсуждалось в перечне почтовых отправлений, однако унифицированное решение еще не принято. Вы можете использовать следующую функцию заполнителя до тех пор, однако, из-за исключением повышения его ни стиль, ни эффективность мудр приятно:

template<typename Target, typename Source> 
    inline Target default_numeric_cast(Source arg, Target def) 
{ 
    try { 
     return numeric_cast<Target,Source>(arg); 
    } catch (...) { 
     return def; 
    } 
} 

Однако заказное решение будет waaay более эффективным.

5
template<class Target, class Source> 
typename boost::numeric::converter<Target,Source>::result_type 
numeric_cast_defaulted(Source arg, Target default_value = Target()) try { 
    return boost::numeric_cast<Target>(Source); 
} 
catch (boost::bad_numeric_cast&) { 
    return default_value; 
} 
Смежные вопросы