所谓的void();在干什么?

问题描述 投票:8回答:5

[我遇到了void();被用作三元运算符的'else'分支中的'no-nothing',作为空指针检查的简写

if(var){
   var->member();
}

as

var ? var->member() : void();

但是我似乎找不到以这种方式使用的void关键字的引用,这是对void关键字本身的函数或函子调用吗?还是对void的类型不进行任何转换?还是仅仅是pass之类的C ++语法?

编辑:在这种情况下,member()的返回类型为void

c++ syntax void
5个回答
3
投票

您只是在“构造”一个​​类型为void的prvalue(出于注释中的原因,不是变量),就像int()将默认构造一个int

[正如其他人在评论中所说,第二种选择是贬义的。三元运算符之所以是ternary,是因为它具有ifthenelse部分。如果不需要else,为什么还要写一个if(var){ var->member(); } else {} 并留空?

这种选择比这更丑陋,更神秘:

var->member()

也许看起来很愚蠢。


1
投票

假设void具有类型var ? var->member() : void();

void

具有类型var->member(),并且评估void()或评估var,如果void()为空。

现在,[expr.type.conv]/2是一个表达式;根据[expr.type.conv]/2,它什么都不做:

如果类型为cv void,并且初始化程序为(){}(在包扩展后,如果有的话),则表达式为指定类型的prvalue,该表达式不执行初始化。


1
投票

[void是一种类型,但是如果后面跟着(),则会初始化类型为prvaluevoid

做这种事情的原因是,var->member()的返回类型为void,并且?:运算符的第二和第三操作数必须相同。

您已经展示了一种获取其中一个操作数的void prvalue的方法,但是有多种方法可以达到相同的效果,

var ? var->member() : throw 42;

throw表达式具有void类型,因此将进行编译。如果nothing当然是var,则不会执行nullptr,因为它会抛出。

此语句将编译且不执行任何操作,

var ? var->member() : []{}();

其中第二个操作数是一个返回void的匿名函数。

和这个,

var ? var->member() : decltype(var->member())(); 

我认为这很清楚地说,“我正在尝试在两个操作数中获得相同的类型”。

话虽这么说,我不明白为什么有人会写这段代码。如果没有有意义的else分支,则该语言中已经存在if构造,而条件?:运算符是该工作的错误工具。


0
投票

我只看到过这样的代码,这些代码是由'旧驾车者'或类似的人编写的。 void()调用基本上不执行任何操作,三元运算符要求您将something放在else分支中,因此人们有时会这样做。if (stuff) { stuff->member(); }也是单线的。

© www.soinside.com 2019 - 2024. All rights reserved.