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

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

3天内不再提示

“+”操作符的使用技巧

CPP开发者 来源: CppMore 2023-12-28 13:27 次阅读

这篇写个平时易被忽略的小知识点,一元 + 操作符的使用技巧。

一般二元 + 操作符用得较多,只有一个操作数时,没人会多此一举地把 1 写成 +1。

不过若是操作数为整数或无作用域枚举类型,一元 + 操作符会执行 Integral promotion,此时会发生隐式转换。例如:

//unscopedenumeration
enumEnum:unsignedint{
enum_val_a,
enum_val_b,
enum_val_c
};

intmain(){

boolb=true;
+b;//int

+enum_val_b;//unsignedint

charc='c';
+c;//int

unsignedshorts=10;
+s;//int

intarray[10];
+array;//int*
}

若是你使用的 C++ 标准不支持 std::to_underlying,你可能得使用以下语句来达到同样目的:

static_cast>(enum_val_b);

这种写法太过繁琐,而以一元 + 操作符则可以非常简单地完成这种转换,当然前提须是 underlying 类型固定。

对于一些奇怪的类型,比如 std::uint8_t,它的类型是什么呢?顾名思义应该是 8-bit 的 Unsigned integer,然而实际上它是 unsigned char 的 typedef。那么在输出的时候就会遇到一些问题:

std::uint8_tu=0x45;
std::cout<< u; // E

最终输出将是 E,并不是一个无符号整数,你需要使用强制转换才能得到想要的输出。而借助一元 + 操作符,则可以非常简单地达到预期。

std::uint8_tu=0x45;
std::cout<< +u; // 69

另外,一元 + 操作符也支持指针类型的操作数,所以它也可以隐式地把 Lambda 转换为函数指针。例如:

autofp=+[]{};
static_assert(std::is_same_v);

如果没有 +,那 fp 只是一个 closure 类型,断言出错。

另一个用法是在 Concepts 中,比如你想判断某类型当中是否存在某变量,可能会这样写:

template
conceptHasValue=requires(Tt){
{T::num}->std::integral;
};

structS{
intnum;
};

//false
static_assert(HasValue);

没能达到预期是因为 T::num 是个 value,而非 type。一种做法是采用 std::is_integral,

template
conceptHasValue=requires(Tt){
std::is_integral_v;
};

//true
static_assert(HasValue);

这种做法就将 T::num 变成了 type,同理也可以这样做:

template
conceptHasValue=requires(Tt){
decltype(T::num){};
};

约束必须是表达式,是以无法只写类型。更简单的话可以这样写:

template
conceptHasValue=requires(Tt){
T::num++;
};

因为自增运算符也可以构成表达式,那么最简单的做法就是采用一元 + 操作符。

template
conceptHasValue=requires(Tt){
+T::num;
};

那么有没有办法可以禁止 Integral promotion 呢?Concepts 便有此妙用。看下面这个例子:

uint8_tbad_foo(uint8_ta,uint8_tb){
returna+b;//implicitconversion
}

std::same_asauto
good_foo(uint8_ta,uint8_tb){
returna+b;//Compileerror!
}

对于 bad_foo(),return a + b 在不经意间发生了 Integral promotion,它其实相当于return uint8_t((int)a + (int)b)。

这种隐式转换的结果可能并不如人所愿,Concepts 相当于给返回值声明了 explict,从而避免错误。当你明确不需要返回值隐式转换的时候,可以借助这种方式。

活用这些小技巧,不仅可以简化代码,还能增加程序安全性。

审核编辑:汤梓红

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

    关注

    21

    文章

    2066

    浏览量

    72900
  • Type
    +关注

    关注

    1

    文章

    132

    浏览量

    22159
  • 操作符
    +关注

    关注

    0

    文章

    20

    浏览量

    8999

原文标题:"+" 的几个使用小技巧,你了解吗

文章出处:【微信号:CPP开发者,微信公众号:CPP开发者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    MATLAB操作符和特殊字符

    MATLAB操作符和特殊字符* 矩阵乘法 .* 数组乘法 ^ 矩阵幂 .^ 数组幂 \ 左除或反斜杠 / 右除或斜杠 ./ 数组除 Kron Kronecker张量积 .. 父目录 … 继续
    发表于 09-22 16:05

    C语言,操作符优先级顺序。

    `下午,在图书馆看了会《C陷阱与缺陷》这本书,看到操作符优先级部分,想着这部分很重要,我就记录下来,方便自己以后查看。先上张图片吧。书中做的总结,我也叙述一下:优先级最高的是非操作符部分
    发表于 01-16 17:30

    【FPGA学习】 Verilog HDL 语言的表达式及操作符详细介绍

    表达式是 Verilog HDL 语言中进行逻辑运算和表达最基本的元素。表达式由操作符操作数按照一定的规则组合而成,下面进行详细介绍。1.操作操作数的类型包括:常量、参数、线网、寄
    发表于 09-20 09:23

    二进制转换如何设置移位操作符

    这些移位操作器是如何设置的。我知道他们正在检查两个的力量,但是他们是如何做到的,如果是的话,我如何将它应用到更高的比特上。如何设置移位操作符?使用SpkFlash和PIC18F45 25的SelLCD
    发表于 11-19 10:44

    操作符的相关资料分享

    嵌入式C语言入门——操作符
    发表于 12-15 06:50

    操作C语言支持的几种位操作符是哪些呢

    一、位操作C语言支持的6种位操作符如下:1.不改变其他位的值的状况下,对某几个位进行设值。方法:先对需要设置的位用&操作符(对应位&0)进行清零操作,然后用|
    发表于 12-22 08:07

    操作符及其常用方式简要概述

    目录前言一、位操作符及其常用方式二、实例应用解析(嵌入式笔试常考)前言位操作在单片机的C语言开发中经常会用到,该操作主要用于读写寄存器,这篇文章将会对其的常用方法进行简要概述。一、位操作符
    发表于 02-17 06:33

    无感方波控制之择多函数逻辑操作符的理解

    如何此处择多函数的操作符所表示的意义?
    发表于 10-14 16:19

    【verilog每日一练】移位操作符的使用

    定义变量reg [7:0]a;reg [7:0]b;reg [7:0]c;暂不考虑溢出及小数,用移位操作符(<<、>>)实现b等于a乘以4的结果,c等于a除以8的结果
    发表于 08-14 10:36

    请问C语言文件中的预处理操作符#和##各有什么作用?

    C语言文件中的预处理操作符#和##各有什么作用?
    发表于 11-06 08:09

    C语言的sizeof操作符基础和经典问题

    在C语言中,sizeof是一个操作符(operator),而不是函数!其用于判断数据类型或者表达式长度(所占的内存字节数)。其有两种表达形式:
    的头像 发表于 04-04 17:39 2408次阅读
    C语言的sizeof<b class='flag-5'>操作符</b>基础和经典问题

    C++:详谈取地址操作符重载

    取址操作符重载函数返回值为该类型的指针,无参数。
    的头像 发表于 06-29 11:59 3256次阅读
    C++:详谈取地址<b class='flag-5'>操作符</b>重载

    C++之操作符重载学习的总结

    操作符重载是c++的强大特性之一;操作符重载的本质是通过函数扩展操作符的功能;operator 关键字是实现操作符重载的关键。
    的头像 发表于 12-24 16:36 515次阅读

    Verilog基础:几个常用的按位操作符

    操作符是对二进制位进行操作的运算符。
    的头像 发表于 11-09 10:57 503次阅读

    Verilog基础:介绍几个常用的按位操作符

    操作符是对二进制位进行操作的运算符。以下是一些常用的位操作符
    的头像 发表于 11-09 10:59 398次阅读