C++ 17: IF and SWITCH With Initialisation

In C++ 17, if statement can have an initialisation clause i.e. instead of

if(condition) {}

this:

if(init; condition) {}

Why? I could just write

init;
if(condition) {}

and it’s almost the same. Initialisation clause is valid until the ned of the if part. To demonstrate:

if (int i = 1; i == 0)
{
    // OK
    cout << "if 1" << endl;
}
else
{
    // OK
    cout << "else:" << i << endl;
}

// left the scope, so the following line won't compile:
cout << i << endl;

This also means RAII applies to the initialisation phase i.e. if init instantiates a class on stack, a destructor will be called.

This is useful in many scenarios, for instance guard initialisation:

if (std::lock_guard<std::mutex> g{mtx}; !coll.empty()) {
	// safely use the collection
}

You can achieve the same in pre C++17 codebase with the following code, which is equivalent to above:

{
    std::lock_guard<std::mutex> g{mtx};
    
    if (!coll.empty()) {
        // safely use the collection
    }
}

it’s just syntaxically longer.

Important note - the object in initialisation clause must have a name, and if it doesn’t, it’s automatically created and destroyed before the first statement inside if executes. Basically, it’s destroyed as soon as possible, so no resources are wasted. It would make sense, as you are not referencing it.

Same goes for switch statement, absolutely no differences from if:

switch(init; condition) {}

Have a question⁉ Contact me.