What is calling void(); doing?

Assuming var->member() has type void,

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

has type void and either evaluates var->member() or evaluates void() if var is null.

Now, void() is an expression; according to [expr.type.conv]/2, it just does nothing:

if the type is cv void and the initializer is () or {} (after pack expansion, if any), the expression is a prvalue of the specified type that performs no initialization.


void is a type, but if it's followed by () it does initialization of a prvalue of type void.

The reason for doing such a thing, is that the return type of var->member() is void, and the second and third operands of ?: operator must be the same. Note: They don't have to be exactly the same; there are conversion rules that say when the the types can be different.

You have shown one way to get a void prvalue for one of the operands, but there are a number of ways to achieve the same effect,

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

a throw expression has the void type, so this compiles. It won't do nothing if var is nullptr of course, since it throws.

This statement will compile and do nothing,

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

where the second operand is an anonymous function returning void.

and this one,

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

which in my opinion says most clearly, "I'm trying to get the same type in both operands".

That being said, I don't see why one would ever write this code. If there's no meaningful else branch, then there is already the if construct in the language, and the conditional ?: operator is the wrong tool for the job.

Edit: @walnut's (now deleted) answer actually shows a use-case: in c++11, but pre-c++14, the ?: operator is the only way to express conditional branches in constexpr functions.


You are just "constructing" a prvalue (not a variable, for the reason suggested in the comments) of type void, just as int() would default-construct an int.

As others said in the comments, the second alternative is pejorative. The ternary operator is, well, ternary because it has the if, the then, and the else parts. If you don't need an else, why would you write one and leave it empty?

That alternative is even uglier and more cryptic than this,

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

which may just look stupid.

Tags:

C++

Syntax

Void