折叠表达式的操作数是否需要加括号?

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

以下program

#include<iostream>

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

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

gcc 打印 1000,但 clang 报错:

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

我不确定我是否理解错误。像这样添加括号:

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

似乎仍然是一个表达式,但现在 clang 也接受它,并且还打印 1000.

此外,fauto 参数无关紧要,用 c++17 编写的等效程序具有相同的行为(如演示所示)。

程序有效吗?

fold-expression ([expr.prim.fold]) 的语法是:

fold-expression:

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

您正在使用第三种形式。您要解析为第一个 cast-expression 的是 shift-expression ([expr.shift]) ,但是 shift-expression 不是 cast-expression,所以这不是有效的 fold-expression.

a >> b的优先级低于(T) c,这是折叠表达式可以接受的最低优先级形式。这是因为下一个最高的是 pointer-to-member 表达式,它本身就是可能的折叠运算符之一,因此可能不明确。