For loop vs For each loop for arrays

What is the difference between for loops and for each loops regarding with using arrays? Can you give example of how for each loop can be used ? What are the advantages ?

@kevinkjt2000 This an example of a range-based for loop (which someone referred to it as for each loop).



1
2
3
4
5
6
7
8
int arr[] = {1, 2, 3, 4};

for (int a : arr){
      cout << x;
      cout << endl;

}



I don't know where exactly I can use it ? and what is the advantage of it comparing to a regular for loop?
Last edited on
Kourosh23, the problem with your code is that arrays don't have range-for loops. Range-for loops approximately equals to this while compile:
1
2
3
for (auto p = c.begin(); p != c.end(); p++) {
// do something with *p
}

Since arrays don't have begin() and end(), no corresponding code can be generated for range-for loop.
@BlueSquirrelJQX
Using the range based for loop is fine with arrays.

Generally range based for loops can be used with all containers where begin()/end() can be used (either as member or as free functions) which includes arrays.

what is the advantage of it comparing to a regular for loop?
It is shorter. There is no more secret behind.
@BlueSquirrelJQX , it is mentioned in my book that range-for loops exist like the example that I provided.


@coder777, I heard someone mentioned that this kind of for loop offers a better solution when we do not know how many values the array contains, so we don't know the size of the array which can be a bit frustrating. However, using for each loop can print the values out even if the size is unknown.

I know that you already mentioned "There is no more secret behind" , but does my explanation provide any further clue to what else they might do ?
@Kourosh23: Size of arrays can still be determined by sizeof(arrayName) / sizeof(typeOfArray).

1
2
int numbers[] = {1, 2, 3, 4, 5};
const std::size_t length_of_numbers = sizeof(numbers) / sizeof(int);
The size of the array must be known in order to use it in a range based loop. In other words: You can't do more with a range based loop than a normal loop. Actually a range based loop is more limited.
You could use an ifinite iterator and have a break statement:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <iterator>

class Integer {
	int a; //some kind of big number class would be used instead of int
public:
	Integer(int a) : a(a) {}
	bool operator==(Integer rhs) { return a == rhs.a; }
	bool operator!=(Integer rhs) { return a != rhs.a; }
	Integer& operator++() { ++a; return *this; }
	friend std::ostream& operator<<(std::ostream& out, Integer rhs) { out << rhs.a; };
	int operator*() { return a; }
	static const int Infinity = -1; //would use some kind of enum probably? and add more comparison operators
};

class Counter {
	Integer current;
public:
	Counter(Integer start) : current(start) {}
	Counter& operator++() { ++current; return *this; }
	int operator*() { return *current; }
	bool operator!=(Counter rhs) { return true; }
};

class Naturals {
public:
	Counter begin() { return Counter(0); }
	Counter end() { return Counter(Integer::Infinity); }
};

int main() {
	for(Integer x : Naturals{}) {
		std::cout << x;
		if(x == 5) break;
		else std::cout << ", ";
	}
}


Functional programming languages typically do stuff like this and rely on lazy evaluation (such as a break; in the middle of a loop of infinite values)
I could probaby use ForIterator and accomplish putting an infinite list into a range-based for loop, but I have to go to work now.
http://stackoverflow.com/a/14920606/2607949


Edit: I decided to give another go at this infinite range-based for code after work, so above is my edited example.
Edit 2: I liked this other syntax a bit better even though it made the code longer.
Last edited on
Actually a range based loop is more limited.

But compact and expressive.
1
2
3
4
for ( auto foo : bar )
{
  // something
}

Says very clearly that here we do something with each element of range bar.

We can write this loop without digging up how many elements are in that range. The compiler will do it for us. The less we have to write, the less we do make mistakes.


That is not as versatile as the old syntax (although you can do black magic and obscure tricks to defeat the clarity with almost every bit of the language).

To quote http://thbecker.net/articles/rvalue_references/section_04.html
As we all know, the First Amendment to the C++ Standard states: "The committee shall make no rule that prevents C++ programmers from shooting themselves in the foot."
There is nothing wrong with using a range based loop when possible.
@kevinkjt2000,

For your code:

1
2
int numbers[] = {1, 2, 3, 4, 5};
const std::size_t length_of_numbers = sizeof(numbers) / sizeof(int);



You have given the elements of the array, so doesn't that easily indicate the size of the array?
It does. The compiler counts the elements in the initializer and uses that info to construct the array. The info is available.

Both of these use that info:
1
2
3
const auto foo = sizeof(numbers);

for ( auto bar : numbers ) // something 
Ok, thank you.
Topic archived. No new replies allowed.