range-based for loop with a iterator of reference type

Hi, everyone. I just encountered a range-based for loop whose iterator is reference type, which confused me a lot. The code is like this. Let's assume that we have some text in a vector of strings and the name of the vector is text. Then, we can print the whole vector by the code below:
for (const auto &s : text)
cout<<s<<endl;
As what I've understood, the s here should be the iterator for the for loop and yet s has a reference type, which doesn't make much sense to me since we can never reassign a reference. When s loops through the first string in the vector, it should have been bound to it as its reference. Then, how come it can continue with the second and the rest strings?
Can someone help me out here. Thanks a lot.

It's called a "for each" loop. It is supported in C++11, and it looks similar to how it's done in Java. If text is a list of Foo objects, s is of type Foo (the "auto" type here is convenient for that).

It's handy syntax when you don't need to know about the positioning index of the object in the list/array itself, it simply goes through *each* object.

Just as
1
2
3
4
void foo(int &var)
{
   var = 31;
} 
Changes the actual value of the parameter itself, doing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
    int a[3] = {3, 4, 5};
    for (int &num : a)
    {
        num = num * 2; //Can change "a", since it's a reference
    }
    
    for (int i = 0; i < 3; i++)
    {
        std::cout << a[i] << std::endl;
    }
    
}

...can change "num", which is the value of the element in the array. The only reason it's
(const auto &s : text) instead of (auto s : text) is for efficiency.
Last edited on
The 's' is not an iterator.

Your example:
1
2
3
4
for ( const auto &s : text )
{
  cout << s << endl;
}

is approximately same as this:
1
2
3
4
5
6
for ( auto i = text.begin(); i != text.end(); ++i )
{
  // decltype(i) ==  decltype(text)::iterator
  const decltype(text)::value_type & s = *i; // const string & s = *i;
  cout << s << endl;
}

To Ganado: not exactly what I asked, but still thanks a lot.

To keskiverto: I think I most or less understand the mechanism now after reading your reply. Does it mean that when we iterate through a for loop, each iteration has its own scope which is outside of that of the other iterations, so when i=text.begin(), we can declare a reference type variable &s here and bind it to some object and later when the iterator is incremented, i becomes (text.begin()+1) and now we can declare another reference type variable which also has the name of &s and bind it to another object since these two &s's are in two different parallel scopes. Do I get right?
Yes.
Okay, thanks a lot!
Topic archived. No new replies allowed.