如何折叠逗号?

时间:2017-08-10 02:34:44

标签: c++ c++17

以下行是如何展开的?

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

应用规则,

  

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

cppreference提供,

E  = void(os << args)
op = , 

然后扩展变为

void(os << args[0], ..., (args[N-3], (args[N-2], args[N-1])) )

怎么样

v.push_back(args), ...

是否成为

v.push_back(args[0], (args[1], ..., (args[N-2], args[N-1])))

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

1 个答案:

答案 0 :(得分:8)

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

  

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

你是对的,op,Evoid(os << args),其中args是包,但是E i 不仅仅是args i ,它是整个表达式 void(os << args#i)。所以:

(void(os << args), ...);

变为(为方便起见使用[]):

void(os << args[0]), void(os << args[1]), void(os << args[2]), ..., void(os << args[N-1]);

相当于:

os << args[0];
os << args[1];
...
os << args[N-1];

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

v.push_back(args[0]), v.push_back(args[1]), ..., v.push_back(args[N-1]);

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

(os << ... << args);

将扩展为:

((((os << args[0]) << args[1]) ... ) << args[N-1]);