I think it's just a matter of consistency with non-auto
declarations.
This:
auto n = 42, *p = &n;
is equivalent to:
int n = 42, *p = &n;
where the types int
and int*
are derived from the initializers. In both cases, even though int
and int*
are different types, they're permitted to be in the same declaration because of their close syntactic relation. (By the "declaration follows use" rule that C and C++ declarations almost follow, you're defining both n
and *p
as being of type int
.)
It would have been possible to permit unrelated types in the same declaration:
auto n = 42, x = 1.5;
but the above would have to be equivalent to two separate declarations:
int n = 42; double x = 1.5;
I think the idea when adding auto
was to make a minimal change to the language, permitting the type to be inferred from an initializer but not changing the kinds of declarations that are possible.
Even without auto
, you could define an int
and an int*
in a for
loop header:
for (int n = 42, *p = &n; expr1; expr2) { /* ... / }
but you couldn't declare an int
and a double
together. The addition of auto
simply didn't change that.
Outside the context of a for
loop, it's generally much better to use separate declarations anyway. Shoving a lot of different declarations into a for
loop is arguably a bad idea in most cases. And for the (probably rare) cases where you want a lot of declarations, you can just put them above the loop, something like this:
auto i=std::begin(c), end=std::end(c),
for( x=*i; i!=end; ++i, x+=*i) {
// ...
}
adding another set of {
}
around the whole thing if you want to limit the scope. (In this case, you'd probably want end
to be const
anyway.)