问题
I need to create multiple functions that will check if an input is valid or not. Here are some of my codes:
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;
}
I'm using the header limits.h for this. Am I doing this the right way? Please take note that I'm just a beginner. I hope you all will understand. Thank you!
回答1:
the template above will not work for the mixture of signed and unsigned types, in addition to floats.
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();
}
}
回答2:
#include <limits>
template<typename ValueType, typename RangeType >
bool IsInRange( ValueType value ) {
return (value >= numeric_limits<RangeType>::min()) &&
(value <= numeric_limits<RangeType>::max());
}
This will work for integral data types except for floating point values. numeric_limits<T>::min()
will return the minimum normalized positive value for floating point types. C++11 introduced numeric_limits<T>::lowest()
to resolve the issue.
回答3:
First off, you don't need all those convolutions with booleans. Just return the expression directly:
return (s >= SCHAR_MIN) && (s <= SCHAR_MAX);
Second, you should realize that both your functions always yield true
: by definition, a signed char
is always in the range [SCHAR_MIN, SCHAR_MAX]
, and an int
is always in the range [INT_MIN, INT_MAX]
.
But if you chose different bounds, this would indeed be the way to do it (taking into account my first remark).
As EdS. suggested, you could use a templated solution to reduce the number of functions/overloads you need:
template<class T>
bool check_range(T value, T min, T max) {
return (value >= min) && (value <= max);
}
回答4:
This is an implementation based on the answer by RadioKat, but it suppresses compiler warnings like:
warning: pointless comparison of unsigned integer with zero
warning: integer conversion resulted in a change of sign
by using template meta programming:
#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 );
}
}
来源:https://stackoverflow.com/questions/18625964/checking-if-an-input-is-within-its-range-of-limits-in-c