0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用C++20比较不同类型的整型值

CPP开发者 来源:CPP开发者 2024-11-11 09:35 次阅读

本篇介绍几个细琐的小特性,可以使代码更加安全可靠。

最常见的情况是采取 for loop 遍历某个容器,比如:

std::vectorv(10);
std::iota(v,0);
for(inti=v.size()-1;i>=0;--i){
std::cout<< v[i] << ' ';
}

乍看之下,似乎并无问题,但实际上却存在安全隐患,若是 v.size() 的结果大于 std::numeric_limits::max(),将产生 UB。

倘若你使用了类型推导,问题会更加明显。

for(autoi=v.size()-1;i>=0;--i){
std::cout<< v[i] << ' ';
}

这会输出超出预期的结果!i 被推导为 unsigned 整型,i >= 0 将永远为真。

这种隐患来自于类型的隐式转换,一般编译器只会给出警告。最简单的解决之法就是保证整型符号的一致性,例如:

for(size_ti=v.size()-1;i< v.size(); --i) {
    std::cout << v[i] << ' ';
}

结束条件也随之变为检测数据范围,以避免条件在逻辑上的无效性。但如此一来,可读性直线降低,C++20 引入了几个与此相关的小特性,可以更安全地解决该问题。

第一个是一系列整型比较函数,它们可以安全地对不同符号的类型进行比较。如:

-1>0u;//true
std::cmp_greater(-1,0u);//false

因此,可以用来安全地比较不同符号的整型。

for(inti=0;std::cmp_less(i,v.size());++i){
std::cout<< i << " " << v[i] << '
';
}

通过使用这些安全的比较函数,代码隐患随之消除。只是无法逆序遍历了,逆序时将 size_t 赋值到 int 依旧有可能产生 UB。

此种情境,更好的方式是采用 std::ssize(),它是一个有符号的 size() 辅助函数,表意更加直接。代码更改为:

for(inti=ssize(v)-1;i>=0;--i){
std::cout<< v[i] << ' ';
}

得益于 ADL,std::ssize() 可以简写为 ssize()。

当然,以上只是示例需要,对于数据遍历,Range-based for loop 是更好的方式,这样能够避免很多易被忽视的错误。

for(constauto&elem:v){
std::cout<< elem << ' ';
}

通过 C++20 Views,还可以在遍历时组合其他操作,如:

for(constauto&elem:v|std::reverse){
std::cout<< elem << ' ';
}

这是可读性最强的方式。

当然,还有许多其他方法,比如迭代器、算法和一些技巧,但在范式上来说,那些方法很难比这里展示的方式更加简洁,就使用来说,记住这里提到的便已足够。

推荐阅读点击标题可跳转

1、深入浅出 C++ 类型擦除

2、性能大杀器:c++中的copy elision

3、Configuring Transitive Dependencies with Modern CMake

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    4327

    浏览量

    62573
  • C++
    C++
    +关注

    关注

    22

    文章

    2108

    浏览量

    73623
收藏 人收藏

    评论

    相关推荐

    C++20新特性解析

    C++之父都说过,C++20C++语言的一次重大变革,引入了大量的新特性。
    发表于 10-08 09:07 1990次阅读

    C6000的数据类型需要将返回类型定义为什么型?

    您好~需要程序所需的时间比较长,用TSCL计时已经不够了,想用Timestamp_get64()这个函数得到64位的计时,但是C6000的数据类型中,只有double是64位的,但
    发表于 12-26 14:03

    c51delay函数不同类型参数的不同效果

    c51delay函数不同类型参数的不同效果
    发表于 01-24 06:55

    STM32CubeIDE不支持C++20语法吗?

    我正在使用 STM32CubeIDE 编写 C++ 代码。IDE 的版本是 1.11.0,它带有 arm-none-eabi-g++ 版本 10.3-2021.10。编译器具有一些 C++20 功能
    发表于 02-02 06:51

    同类型储能电源参与电网调频的效果比较研究

    同类型储能电源参与电网调频的效果比较研究_黄际元
    发表于 01-04 17:05 0次下载

    将不同类型单片机开发进行比较

    同类型单片机开发的比较
    的头像 发表于 07-06 05:25 2577次阅读

    plc整型比较指令的用法

    CMP(整型比较)指令能与正常的触点连接使用,该指令可以放置在正常触点允许放置的任何位置。
    的头像 发表于 04-05 17:14 7213次阅读
    plc<b class='flag-5'>整型</b>数<b class='flag-5'>比较</b>指令的用法

    c51简单delay函数,不同类型字符的延时时间不同

    c51delay函数不同类型参数的不同效果
    发表于 11-29 10:51 11次下载
    <b class='flag-5'>c</b>51简单delay函数,不<b class='flag-5'>同类型</b>同<b class='flag-5'>值</b>字符的延时时间不同

    现代C++20实战手册

    追其根源,C++ 为何如此受欢迎,除了它本身出色的性能,作为一种高级面向对象语言,适用领域极其广泛,小到嵌入式,大到分布式服务器,到处可以见到 C++ 的身影;另一个很重要的原因就是它“最近”不断发布具有有趣功能的新语言标准,也就是 C
    的头像 发表于 01-17 09:55 2908次阅读

    C++20 modules入门

    以前一直有了解C++20的新特性,但是因为编译器对此支持的比较少,所以很少实践。
    的头像 发表于 05-29 15:03 974次阅读
    <b class='flag-5'>C++20</b> modules入门

    C++20 modules基础知识入门

    以前一直有了解C++20的新特性,但是因为编译器对此支持的比较少,所以很少实践。
    的头像 发表于 06-15 11:37 855次阅读
    <b class='flag-5'>C++20</b> modules基础知识入门

    C++20无栈协程超轻量高性能异步库开发实战

    c++20出来有一段时间了。其中一大功能就是终于支持协程了(c++作为行业大哥大级别的语言,居然到C++20才开始支持协程,我也是无力吐槽了,让多少人等了多少年,等了多少青春)但千呼万唤他终于还是
    的头像 发表于 11-09 10:20 1315次阅读

    c语言整型数据的溢出计算

    C语言编程过程中,对于整型数据的溢出问题需要特别关注。当整型数据的超过了它所能表示的范围时,会发生溢出现象,导致结果不准确甚至出现异常。本文将以详尽、详实、细致的方式,分析
    的头像 发表于 11-30 11:45 3400次阅读

    同类型AD转换器的比较

    (Integrating ADC)、闪存型(Flash ADC)以及其他如Σ-Δ(Sigma-Delta)调制型等。以下是对这些不同类型AD转换器的详细比较
    的头像 发表于 10-05 11:36 1354次阅读

    如何使用C++20比较同类型整型

    std::numeric_limits::max(),将产生 UB。 倘若你使用了类型推导,问题会更加明显。
    的头像 发表于 11-11 09:35 131次阅读