折叠表达式的操作数是否需要加括号?
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
.
此外,f
的 auto
参数无关紧要,用 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 表达式,它本身就是可能的折叠运算符之一,因此可能不明确。
以下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
.
此外,f
的 auto
参数无关紧要,用 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 表达式,它本身就是可能的折叠运算符之一,因此可能不明确。