void()是一个有效的C++表达式吗?

17

显然,这个三目运算符可以编译通过,其中一个参数是 void()

void foo() {}

//...
a == b ? foo() : void();

void() 在标准中是有效的表达式,还是只是编译器的一种东西?如果它是有效的,那么它属于哪种类型的表达式?


9
这只是某人想显得聪明。if(a==b){ foo(); } 更清晰,而且具有相同的效果。 - Cássio Renan
1
@CássioRenan,你的版本无法在表达式中使用。 - M.M
@M.M 是的,但我真的想不出这在表达式上有任何有用的用途,因为您无法创建 void 类型的对象。(尽管我会第一个说,我不能想到一个并不意味着它不存在) - Cássio Renan
@M.M,你不能将void()作为参数传递。 - Cássio Renan
既然我们有重复的系统,为什么要回答相同的问题这么多次呢? - xinaiz
显示剩余4条评论
2个回答

21

void() 是一个有效的表达式,产生一个 void 类型的 prvalue。在 C++ 20 中,这将被扩展以包括 void{}。相关章节可参见[expr.type.conv]/2

如果初始化程序是一个括号括起来的单个表达式,则类型转换表达式等同于相应的强制类型转换表达式。否则,如果类型为 cv void 并且初始化程序为 (){}(如果有任何包扩展),则该表达式是指定类型的 prvalue,不执行任何初始化。否则,该表达式是指定类型的 prvalue,其结果对象使用初始化程序进行直接初始化。如果初始化程序是带圆括号的可选表达式列表,则指定类型不得是数组类型。


所以,void{}应该可以编译,但实际上却不能。根据这篇文章,它应该是可以的。但为什么不能呢? - NutCracker
@NutCracker 这只适用于C++20。并不是所有编译器都跟上了步伐。C++20甚至还没有最终确定。 - NathanOliver
@NutCracker 没问题。这是一个必要的补充,尝试使统一初始化更加统一。 - NathanOliver

5
除了其他答案,参考此处的描述: void是一种没有值的类型。它是一个无法完成的不完整类型(因此,不能有void类型的对象)。没有void数组,也没有指向void的引用。但是,指向void的指针和返回void类型的函数(在其他语言中称为过程)是允许的。
这意味着你可以将void类型初始化为任何值a == b ? foo() : void(1)a == b ? foo() : void(1111),但是它不会执行任何操作并且仍然能够成功编译。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接