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

    文章

    2094

    浏览量

    73442
  • Type
    +关注

    关注

    1

    文章

    134

    浏览量

    22628
  • 操作符
    +关注

    关注

    0

    文章

    21

    浏览量

    9027

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

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

收藏 人收藏

    评论

    相关推荐

    Linux命令中“!”操作符的用法

    Linux中的'!'符号或操作符可以用作逻辑否定运算,也可以用于在历史记录中获取命令并进行修改或运行以前执行过的命令。
    发表于 07-05 10:07 1414次阅读

    MATLAB操作符和特殊字符

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

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

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

    操作符的相关资料分享

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

    C++的CIN和COUT操作符的方法

    本内容详细提供了C++的CIN和COUT操作符的方法,主要代码如下: #include using namespace std; const int MAX_EDGE = 100; const int MAX_NODE = 100;
    发表于 08-26 10:29 1402次阅读

    C语言编程二进制位操作符

    C语言编程二进制位操作符
    发表于 03-30 14:09 6次下载

    浅析Linux中命令链接操作符的十个最佳实例

    Linux命令中链接的意思是,通过操作符的行为将几个命令组合执行。
    的头像 发表于 08-10 15:51 2855次阅读

    如何快速入门运维?了解Linux中的10个命令链接操作符

    Linux命令中链接的意思是,通过操作符的行为将几个命令组合执行。Linux中的链接命令,有些像你在shell中写短小的shell脚本,并直接在终端中执行。链接使得自动处理变得更方便。不仅如此,一个无人看管的机器在链接操作符的帮助下能够十分有条理地运行。
    的头像 发表于 10-03 19:33 3012次阅读

    Linux中命令链接操作符的实际应用

    Linux命令中的链接的意思是,通过操作符的行为将几个命令组合执行。Linux中的链接命令,有些像你在shell中写短小的shell脚本,并直接在终端中执行。链接使得自动处理变得更方便。
    发表于 05-06 17:44 823次阅读

    使用51单片机内核的汇编操作符笔记

    本文档的主要内容详细介绍的是使用51单片机内核的汇编操作符笔记。
    发表于 07-19 17:38 1次下载
    使用51单片机内核的汇编<b class='flag-5'>操作符</b>笔记

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

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

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

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

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

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

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

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

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

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