Does the operand to a fold expression need to be parenthesized?

224 views Asked by At

For the following program:

#include<iostream>

auto f(auto ...args) 
{
    (std::cout << 1 << ... << args);
}

int main()
{
    f(0, 0, 0);
}

gcc prints 1000, but clang gives an error:

error: expression not permitted as operand of fold expression
    (std::cout << 1 << ... << args);
     ~~~~~~~~~~^~~~
     (            )

I'm not sure I understand the error. Adding parentheses like this:

((std::cout << 1) << ... << args);

still seems to be an expression but now clang accepts this as well, and also prints 1000.

Also, the auto parameters for f are irrelevant, the equivalent program written in c++17 has the same behavior (as shown in the demo).

So is the program valid?

1

There are 1 answers

1
Artyer On BEST ANSWER

The grammar of a fold-expression ([expr.prim.fold]) is:

fold-expression:

( cast-expression fold-operator ... )
( ... fold-operator cast-expression )
( cast-expression fold-operator ... fold-operator cast-expression )

You are using the third form. What you want to be parsed as the first cast-expression is a shift-expression ([expr.shift]), but a shift-expression is not a cast-expression, so this is not a valid fold-expression.

That is, a >> b has lower precedence than (T) c, which is the lowest precedence form that a fold expression can accept. This is because the next highest is a pointer-to-member expression, which is one of the possible fold operators itself so it could be ambiguous.