c – 摆脱有符号和无符号整数表达式之间的比较的优雅方式

前端之家收集整理的这篇文章主要介绍了c – 摆脱有符号和无符号整数表达式之间的比较的优雅方式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有以下模板:

一个用于未签名,另一个用于签名.有没有什么优雅的方式摆脱编译器警告而不压制它?

warning: comparison between signed and unsigned integer expressions

我需要为每种类型写功能,例如uint8,uint16等..?

template<typename X,typename Y,typename Z,typename std::enable_if<std::is_unsigned<X>::value,bool>::type = true >
void debugValidateParameter( X aValuetocheck,Y aLowerLimit,Z aUpperLimit)
{
   if( (aValuetocheck > aUpperLimit) || (aValuetocheck < aLowerLimit) )
   {
    log("ERROR: ValidateParameters,aValuetocheck = %,aLowerLimit= %,aUpperLimit= %  \n",aValuetocheck,aLowerLimit,aUpperLimit );
    throw(std::out_of_range("Invalid Range"));
   }
}

template<typename X,typename std::enable_if<std::is_signed<X>::value,aUpperLimit );
    throw(std::out_of_range("Invalid Range"));
   }
}

解决方法

让我解释一下你在这里遇到的错误.

对于我来说,您通常希望对所有三个参数使用相同的类型.最直接的解决方案是这个定义:

template<typename X>
void debugValidateParameter( X aValuetocheck,X aLowerLimit,X aUpperLimit)
{
   if( (aValuetocheck > aUpperLimit) || (aValuetocheck < aLowerLimit) )
   {
    log("ERROR: ValidateParameters,aUpperLimit );
    throw(std::out_of_range("Invalid Range"));
   }
}

但是,如果然后使用无符号变量和两个文字整数来调用函数,例如:

debugValidateParameter(someUnsignedInteger,100);

您将收到一个错误,因为该类型不能推导出来 – 因此,所有类型为X的参数都需要传递一个完全相同类型的值.
所以推断X型是不明确的,因此是不可能的.对我来说,它看起来像是要根据传递的第一个参数(“实际值”)推导出类型,并且只是尝试将边界转换为同一类型.换句话说,一些不强迫你写的东西

debugValidateParameter(someUnsignedInteger,0u,100u);

这可以通过禁用第二和第三参数的类型扣除来实现,通过将它们的类型指定为identity_t< X>而不是只有X,其中identity_t被定义为

template<typename T>
struct identity { typedef T type; };

template<typename T>
using identity_t = typename identity<T>::type;

所以你的功能定义就变成了

template<typename X>
void debugValidateParameter( X aValuetocheck,identity_t<X> aLowerLimit,identity_t<X> aUpperLimit)
{
   if( (aValuetocheck > aUpperLimit) || (aValuetocheck < aLowerLimit) )
   {
    log("ERROR: ValidateParameters,aUpperLimit );
    throw(std::out_of_range("Invalid Range"));
   }
}

在这里可以看到Live Demo中的代码.

猜你在找的C&C++相关文章