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)

Author: VladD, 2018-04-24

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:

  1. If v is an array of size n, then "start" and "end" are just v and v + n.
  2. For a class-type object v with members begin and end (both must be present), "start" and "end" are the results of calls to v.begin() and v.end().
  3. For everything else, "start" and "end" are the results of calls to begin(v) and end(v), where the names begin and end are searched only in the v associated namespaces

Some consequences of such a specification are:

  1. 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.
  2. It is not possible to pre-define the behavior for embedded arrays by overloading the functions begin and end - these functions will simply be ignored.
  3. For a similar reason, it is not possible to "externally" define behavior for classes that already have their own internal begin and end.
  4. For types that use external begin and end, these begin and end must be declared directly in the associated namespaces. Declared in the spanning namespaces begin and end will not be found

    namespace 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`
        {}
    }
    
 13
Author: AnT, 2019-12-03 18:02:14

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).

 2
Author: Harry, 2018-04-24 19:00:48