Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't compilers expand arguments of a variadic template via comma operator?

I know that we can't use variadic expansions as if it is a chain of comma operators. In that question the sample is like this:

template<typename... Args>
inline void increment_all(Args&... args) 
{
    ++args...; 
}

It might be ambiguous either to increment or expand first so parentheses won't hurt:

template<typename... Args>
inline void increment_all(Args&... args)
{
    (++args)...; 
}

or something like this:

template<typename... Args>
void cout_all(Args&&... args)
{
    (std::cout << std::forward<Args>(args))...; 
}

I know that we can use some recursion tricks to get what we want, like this. What I don't know is why does not the standard describe such behavior? I mean, what is the reason behind it?

like image 682
zahir Avatar asked Jan 20 '13 22:01

zahir


1 Answers

The other contexts where a pack expansion is allowed are lists where a comma is a separator between list elements, not an operator.

For example, f(args...) expands to a function argument list, tuple<Args...> expands to a template argument list.

In your examples the pack expansion forms a statement, and commas between sub-expressions of a statement are the comma operator, which could be overloaded, leading to arbitrarily complicated code, and unlike the builtin comma operator, not forcing left-to-right evaluation. You'd be surprised if your (std::cout << std::forward<Args>(args))...; example wrote out the args in unspecified order because one of the types in the parameter pack overloaded operator<< and operator, and broke the order of evaluation.

Doing this would not be a simple extension to the current rules, it would be a completely different context with very different effects.

It might be ambiguous either to increment or expand first so parentheses won't hurt:

No, it wouldn't be ambiguous. It's OK to use f(++args...) and it's clear and unambiguous. The difficulty with your suggestion is not how to parse ++args... it's what happens after you expand it to a statement containing comma operators.

like image 60
Jonathan Wakely Avatar answered Sep 23 '22 01:09

Jonathan Wakely