Мне нужно создать несколько функций, которые будут проверять, является ли вход действительным или нет.
Вот некоторые из моих кодов:
bool IsValidRange(signed char s)
{
bool isValid = true;
if (!((s>=SCHAR_MIN)&&(s<=SCHAR_MAX)))
{
isValid = false;
}
return isValid;
}
bool IsValidRange(int s)
{
bool isValid = true;
if (!((s>=INT_MIN)&&(s<=INT_MAX)))
{
isValid = false;
}
return isValid;
}
Я использую для этого заголовок limit.h. Я делаю это правильно? Пожалуйста, обратите внимание, что я только начинающий. Я надеюсь, что вы все поймете. Спасибо!
шаблон выше не будет работать для смеси типов со знаком и без знака, в дополнение к плавающим.
template<typename RangeType, typename ValueType >
bool IsInRange( ValueType value )
{
if( ! numeric_limits<RangeType>::is_integer )
{
return (value > 0 ? value : -value) <= numeric_limits<RangeType>::max();
}
if ( numeric_limits<RangeType>::is_signed ==
numeric_limits<ValueType>::is_signed )
{
return value >= numeric_limits<RangeType>::min() &&
value <= numeric_limits<RangeType>::max();
}
else if( numeric_limits<RangeType>::is_signed )
{
return value <= numeric_limits<RangeType>::max();
}
else
{
return value >= 0 && value <= numeric_limits<RangeType>::max();
}
}
#include <limits>
template<typename ValueType, typename RangeType >
bool IsInRange( ValueType value ) {
return (value >= numeric_limits<RangeType>::min()) &&
(value <= numeric_limits<RangeType>::max());
}
Это будет работать для целочисленных типов данных, за исключением значений с плавающей запятой. numeric_limits<T>::min()
вернет нормализованный минимум положительный значение для типов с плавающей запятой. C ++ 11 представлен numeric_limits<T>::lowest()
решить вопрос.
Во-первых, вам не нужны все эти свертки с логическими значениями. Просто верните выражение напрямую:
return (s >= SCHAR_MIN) && (s <= SCHAR_MAX);
Во-вторых, вы должны понимать, что обе ваши функции всегда дают true
по определению signed char
всегда в диапазоне [SCHAR_MIN, SCHAR_MAX]
и int
всегда в диапазоне [INT_MIN, INT_MAX]
,
Но если бы вы выбрали разные границы, это действительно был бы способ сделать это (принимая во внимание мое первое замечание).
Как EdS. Предполагается, что вы можете использовать шаблонное решение, чтобы уменьшить количество необходимых вам функций / перегрузок:
template<class T>
bool check_range(T value, T min, T max) {
return (value >= min) && (value <= max);
}
Это реализация, основанная на ответе RadioKat, но она подавляет предупреждения компилятора, такие как:
warning: pointless comparison of unsigned integer with zero
warning: integer conversion resulted in a change of sign
с помощью шаблонного метапрограммирования:
#include <limits>
template< typename T_Range, typename T_Value, bool T_RangeSigned, bool T_ValueSigned >
struct InIntegerRange;
template< typename T_Range, typename T_Value >
struct InIntegerRange< T_Range, T_Value, false, false >
{
bool operator()( T_Value const & x )
{
return x >= std::numeric_limits< T_Range >::min() &&
x <= std::numeric_limits< T_Range >::max();
}
};
template< typename T_Range, typename T_Value >
struct InIntegerRange< T_Range, T_Value, false, true >
{
bool operator()( T_Value const & x )
{
return x >= 0 && x <= std::numeric_limits< T_Range >::max();
}
};
template< typename T_Range, typename T_Value >
struct InIntegerRange< T_Range, T_Value, true, false >
{
bool operator()( T_Value const & x )
{
return x <= std::numeric_limits< T_Range >::max(); /* x >= 0 is given */
}
};
template< typename T_Range, typename T_Value >
struct InIntegerRange< T_Range, T_Value, true, true >
{
bool operator()( T_Value const & x )
{
return x >= std::numeric_limits< T_Range >::min() &&
x <= std::numeric_limits< T_Range >::max();
}
};
template< typename T_Range, typename T_Value >
inline bool inRange( T_Value const & x )
{
if( std::numeric_limits< T_Range >::is_integer )
{
return InIntegerRange< T_Range, T_Value,
std::numeric_limits< T_Range >::is_signed,
std::numeric_limits< T_Value >::is_signed >()( x );
}
else
{
return ( x > 0 ? x : -x ) <= std::numeric_limits< T_Range >::max() ||
( std::isnan(x) && std::numeric_limits< T_Range >::has_quiet_NaN ) ||
( std::isinf(x) && std::numeric_limits< T_Range >::has_infinity );
}
}