2017-08-10 22 views
4

以下行如何展开?折叠逗号如何工作?

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

应用所述规则,

一元右倍(E OP ...)为E 1个运算(OP ...(E N-1运算ËÑ ))

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]))) 

两膨胀和括号是混乱。有人会解释吗?

回答

7

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

一元右倍(E OP ...)为E 1个运算(OP ...(E N-1运算ËÑ))

你说得对,op,Evoid(os << args),其中args是包,但是电动不仅仅是ARG游戏,这是整个表达式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]); 
+1

需要注意的是二进制左折叠也将保证评价的顺序所有这些'<<'表达式。而逗号的折叠不会。 –

+0

为什么? [在逗号表达式E1,E2中,评估表达式E1,其结果被丢弃(尽管它具有类类型,直到包含完整表达式结束时才会被销毁),并且其副作用在评估表达式E2开始](http://en.cppreference.com/w/cpp/language/operator_other#Built-in_comma_o​​perator),所以在我看来“折叠(内置)逗号”确实保持顺序的评估。 –

+1

@NicolBolas不是吗? http://eel.is/c++draft/expr.comma#1.sentence-3 – Barry