What does for(int x: vector) mean?)
I recently studied c++ from Stroustrup's book , and got to the vectors, here is an example of the code for passing through all the elements of the vector
vector<int> v = { 5,7,9,4,6,8 };
for (int x : v)
cout << x << endl;
But I don't understand what this condition does:for(int x : v)
2 answers
Range-based for-loop has appeared in the language since C++11.
By definition, in this particular case (for v
of type std::vector<int>
), the entry
for (int x : v)
cout << x << endl;
Equivalent to
vector<int>::iterator b = v.begin();
vector<int>::iterator e = v.end();
for (; b != e; ++b)
{
int x = *b;
cout << x << endl;
}
In general, a cycle of the form
for ( decl-x : v )
// тело цикла
(where decl-x
is a declaration), interpreted as
{
auto b = /* начало v */;
auto e = /* конец v */;
for (; b != e; ++b)
{
decl-x = *b;
// тело исходного цикла
}
}
And "beginning v
" and "end v
" are defined depending on the type of v
:
- If
v
is an array of sizen
, then "start" and "end" are justv
andv + n
. - For a class-type object
v
with membersbegin
andend
(both must be present), "start" and "end" are the results of calls tov.begin()
andv.end()
. - For everything else, "start" and "end" are the results of calls to
begin(v)
andend(v)
, where the namesbegin
andend
are searched only in thev
associated namespaces
Some consequences of such a specification are:
- The end of the iterated range is stored until the beginning of the cycle, i.e. attempts to expand/narrow/reallocate the range during the cycle will not affect the stored value and, in general, will not lead to anything good.
- It is not possible to pre-define the behavior for embedded arrays by overloading the functions
begin
andend
- these functions will simply be ignored. - For a similar reason, it is not possible to "externally" define behavior for classes that already have their own internal
begin
andend
. -
For types that use external
begin
andend
, thesebegin
andend
must be declared directly in the associated namespaces. Declared in the spanning namespacesbegin
andend
will not be foundnamespace N { struct S {}; } int *begin(N::S &s) { return 0; } int *end(N::S &s) { return 0; } int main() { N::S s; for (int x : s) // Ошибка - нет `begin` и `end` {} }
Loop for
over the range. Such "syntactic sugar"
for(int x : v)
The x
variable takes all the values from the vector in turn (and not just the vector - it can be another standard container or array).