我发现在void();三元运算符的“else”分支中被用作“什么都不做”,作为空指针检查的简写
Run Code Online (Sandbox Code Playgroud)if(var){ var->member(); }
作为
var ? var->member() : void();
但我似乎找不到对以void这种方式使用的关键字的任何引用,这是对void关键字本身的函数调用还是函子调用?或者它对 的类型没有任何影响void?或者这只是类似的 C++ 语法pass?
编辑:的返回类型member()就是void在这种情况下。
Enr*_*lis 10
您只是在“构造”一个 prvalue(不是变量,原因在评论中建议),类型为void,就像int()默认构造一个int.
正如其他人在评论中所说,第二种选择是贬义的。三元运算符,好,三元因为它具有if的then,而else部分。如果你不需要else,为什么要写一个并将其留空?
这种替代方案比这更丑陋、更神秘:
if(var){
var->member();
} else {}
Run Code Online (Sandbox Code Playgroud)
这可能看起来很愚蠢。
假设var->member()有类型void,
var ? var->member() : void();
Run Code Online (Sandbox Code Playgroud)
有类型void并且要么评估var->member()要么评估void()如果var为空。
现在,void()是一个表达式;根据[expr.type.conv]/2,它什么都不做:
如果类型是cv
void并且初始化器是()or{}(在包扩展之后,如果有),则表达式是不执行初始化的指定类型的纯右值。
void是一个类型,但如果它后面跟着()它会初始化一个prvalue类型void。
这样做的原因,是返回类型var->member()是void,并且?:operator的第二个和第三个操作数必须相同。注意:它们不必完全相同;有转换规则说明什么时候类型可以不同。
您已经展示了一种获得void其中一个操作数的纯右值的方法,但有多种方法可以实现相同的效果,
var ? var->member() : throw 42;
Run Code Online (Sandbox Code Playgroud)
一个throw表达式具有void的类型,所以这种编译。nothing如果var是的话就不行nullptr,当然,因为它会抛出。
这个语句将编译并且什么都不做,
var ? var->member() : []{}();
Run Code Online (Sandbox Code Playgroud)
其中第二个操作数是一个匿名函数返回 void.
和这个,
var ? var->member() : decltype(var->member())();
Run Code Online (Sandbox Code Playgroud)
在我看来,这最清楚地说,“我试图在两个操作数中获得相同的类型”。
话虽如此,我不明白为什么有人会写这段代码。如果没有有意义的 else 分支,那么if语言中已经存在构造,并且有条件?:运算符是错误的工作工具。
编辑:@walnut(现已删除)的答案实际上显示了一个用例:在 c++11 中,但在 c++14 之前,?:运算符是在 constexpr 函数中表达条件分支的唯一方法。