Search code examples
c++c++17structured-bindings

structured binding initializer inside if statement does not compile


Reading up on C++17 and now multiple initializations inside if statement is possible:

if (int x = func(), y = func2(); x > 0 && y > 0)
{
}

Nice one, also in combination with another feature in C++17, structured bindings:

if (auto[iter, success] = set.insert("Hello"); success)
{   }
else    
{   }

But combining both features does not compile in VisualStudio 2017.

if (auto[iter, success] = set.insert("Hello"), [iter2, success2] = set.insert("Foo"); success && success2)
{}
else
{}

missing ';' before ','

Is this is a bug in VS2017 or is this not possible?


Solution

  • MSVC is right on the money in this one. This stems for the grammar alone:

    selection-statement:  
        if ( init-statement condition )
    
    init-statement:
        simple-declaration
    
    simple-declaration:
        decl-specifier-seq init-declarator-list;
        decl-specifier-seq ref-qualifier [ identifier-list ] initializer ;
    

    It's summarized above from all over the standard (with some optional things removed for brevity), but the start point is at [stmt.select]/1.

    The crux of the matter is that a simple-declaration is either a comma separated list of declarators that introduce objects of the same type1 (decl-specifier-seq init-declarator-list;) or a single structured binding (the second, rather verbose line under simple-declaration).


    1 Not strictly the same type (int x, *y;), but the the point should be clear.