我想创建一个函数来检查参数是否超出范围。
我写了这个:
template<typename X,typename Y,typename Z >
void checkParameter( X val, Y lower, Z upper)
{
if( ( val > upper) || ( val < lower) )
{
log("checkParameter, val = % , lower= % , upper= % \n", val,
lower,upper );
ASSERT(false);
}
}
但是,当我这样做时
uint32_t var = 5000;
checkParameter( var, 0, 262143);
我收到警告:
warning: comparison between signed and unsigned integer expressions
如何制作一个安全地处理所有类型的功能?
答案 0 :(得分:1)
正如@Borisbn所说,你可以这样做:
template<typename type >
void checkParameter( type val, type lower, type upper)
{
if( ( val > upper) || ( val < lower) )
{
log("checkParameter, val = % , lower= % , upper= % \n", val,
lower,upper );
ASSERT(false);
}
}
我认为你可以这样做:
template<bool A, bool B, bool C>
struct test {
template < typename T1, typename T2, typename T3>
void parameters (T1, T2, T3) { /* Mismatching types */ }
};
template<>
struct test<true, true, true> { // all parameters will be signed
template < typename T1, typename T2, typename T3>
void parameters (T1 a, T2 b, T3 c) {
/* do your test here */
}
};
template<>
struct test<false, false, false> { //all parameters will be unsigned
template < typename T1, typename T2, typename T3>
void parameters (T1 a, T2 b, T3 c) {
/* do your test here */
}
};
template < typename T1, typename T2, typename T3>
void testParameters(T1 a, T2 b, T3 c) {
test<std::is_signed<T1>::value, std::is_signed<T2>::value, std::is_signed<T3>::value>::parameters(a,b,c);
}
答案 1 :(得分:1)
使用一个在符号不匹配的情况下返回正确结果的函数,而不是使用内置operator <
template<class A, class B>
bool lt(A a, B b)
{
if (a < 0 && b >= 0)
return true;
if (a >= 0 && b < 0)
return false;
return a < b;
}
你仍然会收到警告,所以你可能还想要一些#pragma GCC diagnostic push; ignored; pop
。
答案 2 :(得分:1)
作为o11c和Ajay的答案的组合,您可以使用此比较功能,它不会产生任何警告:
template<typename A, typename B>
bool lt(A a, B b) {
if (a < 0 && b >= 0)
return true;
if (a >= 0 && b < 0)
return false;
using TYPE = decltype(a + b);
return static_cast<TYPE>(a) < static_cast<TYPE>(b);
}
它适用于有符号和无符号数字类型的任意组合。
答案 3 :(得分:0)
你需要推断出三者中最大的类型。您可以使用这种方法:
template<typename X, typename Y, typename Z >
void checkParameter(X val, Y lower, Z upper)
{
using TYPE = decltype(val + lower + upper);
if (((TYPE) val > (TYPE) upper) || ((TYPE) val < (TYPE)lower))
{
ASSERT(false);
}
}
您的编译器应该支持decltype
以及此using
构造。