I recall someone once telling me,
"there is no need for auto
inside range-based for loops. It would
not be ambiguous in the language if we were to remove it."
Is that a true statement?
Is the folowing code valid C++ syntax?
for (elem : range){...}
I had assumed this was already valid syntax, but when I went to compile with
clang++ --std=c++1z
, I was shown the following error:
range-based for loop requires type for loop variable
for (elem: range){
The compiler still recognizes this as a range-based for loop, so why can't it also derive the type?
The:
for (elem : range){...}
syntax is not currently valid but there was a proposal to make this valid syntax and the syntax is supported in gcc 5.2 (see it live):
#include <vector>
int main()
{
std::vector<int> v ;
for( elem : v )
{
}
}
and if we try this in C++14 mode it says:
warning: range-based for loop without a type-specifier only available
with -std=c++1z or -std=gnu++1z
So this would clearly work and has been implemented in gcc. It looks like this feature was removed in gcc 6.0.
As far as I can tell this was implemented in gcc with the expectation that proposal N3853: Range-Based For-Loops: The Next Generation would be accepted but it was rejected and the updated version N3994 says:
This updates N3853 (see [1]) which proposed the syntax "for (elem :
range)", by adding support for attributes and answering additional
questions. Please see the original proposal for the rationale behind
this feature, which is not repeated here.
We can see it was rejected from the EWG issue 81 and we can also see this from the Urbana meeting minutes. Although there are many issues with the proposal I believe STL made a convincing set of arguments in the Question and Answers section of the proposal and I was disappointed that the proposal was rejected.
The syntax requires a type for a range-for statement, even if it's auto
. for (elem : range) {...}
is a syntax error, so technically, yes, it's true, the language could state that this is equivalent to for (auto elem : range) {...}
.
There are at least two major problems with that, though:
The first is that for (T elem : range)
doesn't require T
to use auto
. If the compiler sees for (elem
, it wouldn't yet have any way of knowing whether elem
is some typedef
from an outer scope, or a newly declared variable. It's not ambiguous, but it's a bit complicated for compilers to handle correctly.
The second is that you then get the question of what the default should be. Legitimate arguments could be made for auto
. Legitimate arguments could be made for auto &
. Legitimate arguments could be made for const auto &
. The current approach just lets the programmer choose. Legitimate arguments could probably (I'm not entirely sure) also be made for some of those with auto
replaced by decltype(auto)
.
This is really a question for ELL...
The sentence is written in the subjunctive case, meaning that it is talking about a purely hypothetical situation, not the actual language rules. Subjunctive is used for counterfactual situations.