1

对于以下程序

#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.

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

那么这个程序有效吗?

4

1 回答 1

2

折叠表达式([expr.prim.fold])的语法是:

折叠表达式

( 强制转换表达式 折叠运算符 ... )
( ... 折叠运算符 强制转换表达式 )
( 强制转换表达式 折叠运算符 ... 折叠运算符 强制转换表达式 )

您正在使用第三种形式。您希望作为第一个cast-expression被解析的是shift-expression ([expr.shift]),但shift-expression不是cast-expression,因此这不是有效的fold-expression

也就是说,a >> b优先级低于(T) c,这是折叠表达式可以接受的最低优先级形式。这是因为下一个最高的是指向成员的表达式,它本身就是可能的折叠运算符之一,因此它可能是模棱两可的。

于 2020-10-04T17:43:33.337 回答