什么叫 void(); 正在做?

Jay*_*Jay 17 c++ syntax void

我发现在void();三元运算符的“else”分支中被用作“什么都不做”,作为空指针检查的简写

if(var){
   var->member();
}
Run Code Online (Sandbox Code Playgroud)

作为

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

但我似乎找不到对以void这种方式使用的关键字的任何引用,这是对void关键字本身的函数调用还是函子调用?或者它对 的类型没有任何影响void?或者这只是类似的 C++ 语法pass

编辑:的返回类型member()就是void在这种情况下。

Enr*_*lis 10

您只是在“构造”一个​​ prvalue(不是变量,原因在评论中建议),类型为void,就像int()默认构造一个int.

正如其他人在评论中所说,第二种选择是贬义的。三元运算符,好,三元因为它具有ifthen,而else部分。如果你不需要else,为什么要写一个并将其留空?

这种替代方案比这更丑陋、更神秘:

if(var){
   var->member();
} else {}
Run Code Online (Sandbox Code Playgroud)

这可能看起来很愚蠢。

  • @WhozCraig 奇怪的是,**[expr.type.conv]** 是这么说的:“如果类型是 `cv void` 并且初始化器是 `()`,则表达式是指定类型的纯右值,不执行任何操作初始化。” 这表明可以有一个类型为“void”的纯右值(尽管不是左值,这就是“变量”所暗示的含义)。 (2认同)

YSC*_*YSC 8

假设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()”不是一个值或一个虚拟的非值。可以用作 `void Foo() { return void(); (为什么要这样做? T 是 `void` 的模板,您需要返回 `T()` 并且您不必仅仅为了处理 T = `void` 边缘情况而执行 SFINAE 恶作剧)。但不能用于调用 `Foo(void());` 因为那太明显了。C++ 没有实际的_底层类型_。它几乎没有_unit类型_(即`std::monostate`...但它也有0元组`std::tuple<>`,以及任何退化结构`struct Unit_t {};`)。或者无论“退化”结构的正确术语是什么。 (2认同)

cig*_*ien 7

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 函数中表达条件分支的唯一方法。