How does the following line unfold?
template <class... Ts>
void print_all(std::ostream& os, Ts const&... args) {
(void(os << args), ...);
}
Applying the rule,
Unary right fold (E op ...) becomes E1 op (... op (EN-1 op EN))
provided by cppreference,
E = void(os << args)
op = ,
Then the expansion becomes
void(os << args[0], ..., (args[N-3], (args[N-2], args[N-1])) )
?
How about
v.push_back(args), ...
Does it become
v.push_back(args[0], (args[1], ..., (args[N-2], args[N-1])))
Both the expansion and the parenthesis are confusing. Would someone explain?
You have to unpack the entire expression that contains the parameter pack. Not just the parameter pack. Just following the rules:
Unary right fold (E op ...) becomes E1 op (... op (EN-1 op EN))
You're right that op
is ,
and E
is void(os << args)
, where args
is the pack, but Ei isn't just argsi, it's the whole expression void(os << args#i)
. So:
(void(os << args), ...);
becomes (using []
for convenience):
void(os << args[0]), void(os << args[1]), void(os << args[2]), ..., void(os << args[N-1]);
which is equivalent to:
os << args[0];
os << args[1];
...
os << args[N-1];
Similarly, (v.push_back(args), ...)
(the parentheses are required) would expand as:
v.push_back(args[0]), v.push_back(args[1]), ..., v.push_back(args[N-1]);
Note that you could also write this example as a binary left fold:
(os << ... << args);
which would expand as:
((((os << args[0]) << args[1]) ... ) << args[N-1]);
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy