如何折叠逗号?

Can*_*hiu 6 c++ c++17

以下行是如何展开的?

template <class... Ts>
void print_all(std::ostream& os, Ts const&... args) {
    (void(os << args), ...);
}
Run Code Online (Sandbox Code Playgroud)

应用规则,

一元右折(E op ...)变为E 1 op(... op(E N-1 op E N))

cppreference提供,

E  = void(os << args)
op = , 
Run Code Online (Sandbox Code Playgroud)

然后扩张成为

void(os << args[0], ..., (args[N-3], (args[N-2], args[N-1])) )
Run Code Online (Sandbox Code Playgroud)

怎么样

v.push_back(args), ...
Run Code Online (Sandbox Code Playgroud)

它变成了吗?

v.push_back(args[0], (args[1], ..., (args[N-2], args[N-1])))
Run Code Online (Sandbox Code Playgroud)

扩展和括号都令人困惑.有人解释一下吗?

Bar*_*rry 9

您必须解压缩包含参数包的整个表达式.不只是参数包.遵守规则:

一元右折(E op ...)变为E 1 op(... op(E N-1 op E N))

你说得对,op,Evoid(os << args),这里args是包,但è 不只是ARGS ,它的整体表现 void(os << args#i).所以:

(void(os << args), ...);
Run Code Online (Sandbox Code Playgroud)

成为([]为方便起见):

void(os << args[0]), void(os << args[1]), void(os << args[2]), ..., void(os << args[N-1]);
Run Code Online (Sandbox Code Playgroud)

这相当于:

os << args[0];
os << args[1];
...
os << args[N-1];
Run Code Online (Sandbox Code Playgroud)

同样,(v.push_back(args), ...)(括号是必需的)将扩展为:

v.push_back(args[0]), v.push_back(args[1]), ..., v.push_back(args[N-1]);
Run Code Online (Sandbox Code Playgroud)

请注意,您也可以将此示例编写为二进制左折叠:

(os << ... << args);
Run Code Online (Sandbox Code Playgroud)

将扩展为:

((((os << args[0]) << args[1]) ... ) << args[N-1]);
Run Code Online (Sandbox Code Playgroud)

  • 为什么需要强制转换为 void? (3认同)