c++ - C ++如何禁用具有不同符号变量比较的特定行的编译器警告?
问题描述
我的 C++ 项目中有一个烦人的编译器警告。它在一个模板函数中,它检查它的参数是否适合特定类型的范围,这被称为模板参数(在标准库中找不到它,它有吗?)。
我知道有符号到无符号整数类型的比较很棘手,因此我专门为不同的有符号整数使用了这个函数,在有符号整数与无符号比较之前,我首先检查有符号整数是否为非负数。但是 gcc 会针对这种安全情况发出警告。我不想用 -Wsign-compare 完全禁用这个警告,因为它很有用。代码如下:
template <typename TRange, typename TSuspect, typename TCommonSignedness>
bool isInRangeOfHelper(const TSuspect & suspect,
const TCommonSignedness &,
const TCommonSignedness &)
{
return std::numeric_limits<TRange>::min() <= suspect
&& suspect <= std::numeric_limits<TRange>::max();
}
template <typename TRange, typename TSuspect>
bool isInRangeOfHelper(const TSuspect & suspect,
const std::true_type &,
const std::false_type &)
{
return suspect <= std::numeric_limits<TRange>::max();
}
template <typename TRange, typename TSuspect>
bool isInRangeOfHelper(const TSuspect & suspect,
const std::false_type &,
const std::true_type &)
{
return 0 <= suspect
&& suspect <= std::numeric_limits<TRange>::max(); // WARNING HERE
}
template <typename TRange, typename TSuspect>
bool isInRangeOf(const TSuspect & suspect){
return isInRangeOfHelper<TRange>(suspect,
std::is_signed<TRange>(),
std::is_signed<TSuspect>());
}
template <typename TRange>
bool isInRangeOf(const TRange & suspect){ return true; }
int main(int argc, char *argv[]){
if (!isInRangeOf<unsigned int>(-1)){
std::cout << "false";
} else {
std::cout << "predicate error";
std::terminate();
}
return 0;
}
// warning: comparison of integer expressions of different signedness:
// ‘const int’ and ‘unsigned int’ [-Wsign-compare]
// return 0 <= suspect && suspect <= std::numeric_limits<TRange>::max();
// ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
解决方案
一旦你验证suspect
了它是非负的,你就可以安全地将它转换为它的类型的无符号版本:
template <typename TRange, typename TSuspect>
bool isInRangeOfHelper(const TSuspect & suspect,
const std::false_type &,
const std::true_type &)
{
return 0 <= suspect
&& static_cast<std::make_unsigned_t<TSuspect>>(suspect) <= std::numeric_limits<TRange>::max();
}
推荐阅读
- java - 具有不同 url 但具有相同参数和相同方法功能的请求映射
- c# - 如何获取 JSON 格式的令牌
- python - sklearn混淆矩阵错过了一些结果
- android - 如何膨胀视图集条件是否为空
- c++ - const 好的,但不是 constexpr?
- json - 如何从 SQL 中的 FROM OPENJSON() WITH 中的十进制值中删除 .0
- java - 将 FirebaseDatabase jsonObject 转换为 jsonArray,然后将 jsonArray 转换为 .xlsx 格式
- html - 保护 HTML LocalStorage
- elasticsearch - 意外发生错误“默认情况下在文本字段上禁用字段数据”
- delphi - 在 Delphi 中创建表生成器