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?
The grammar of a fold-expression ([expr.prim.fold]) is:
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.