Enhanced FOR loops in C++

I am switching from Java to C++ and I was wondering whether C++ contains the enhanced for loops that I used in java, in example:

int[] numbers = {1,2,3,4,5,6,7,8,9,10};
for (int item : numbers) {
  System.out.println("Count is: " + item);
}

Is this same "shortcut" possible in C++?


C++11 does. They are called range-based fors. Remember that you should qualify the type as a reference or a reference to const.

The workaround for C++03 is BOOST_FOR_EACH or boost::bind in combination with std::for_each. More fancy things are possible with Boost.Lambda. Should you be in the mood to frustrate either yourself or your co-workers I recommend the deprecated binders std::bind1st and std::bind2nd.

Here is some example code:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <boost/lambda/lambda.hpp>
#include <functional>    

int main()
{
  int i = 0;
  std::vector<int> v;
  std::generate_n(std::back_inserter(v), 10, [&]() {return i++;});

  // range-based for
  // keep it simple
  for(auto a : v)
    std::cout << a << " ";
  std::cout << std::endl;

  // lambda
  // i don't like loops
  std::for_each(v.begin(), v.end(), [](int x) { 
      std::cout << x << " ";
    });
  std::cout << std::endl;

  // hardcore
  // i know my lib
  std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
  std::cout << std::endl;


  // boost lambda
  // this is what google came up with
  // using for the placeholder, otherwise this looks weird
  using namespace boost::lambda;
  std::for_each(v.begin(), v.end(), std::cout << _1 << " ");
  std::cout << std::endl;

  // fold
  // i want to be a haskell programmer
  std::accumulate(v.begin(), v.end(), std::ref(std::cout), 
                  [](std::ostream& o, int i) -> std::ostream& { return o << i << " "; });

  return 0;
}

In C++11, if your compiler supports it, yes it is. It's called range-based for.

std::vector<int> v;

// fill vector

for (const int& i : v) { std::cout << i << "\n"; }

It works for C style arrays and any type that has functions begin() and end() that return iterators. Example:

class test {
    int* array;
    size_t size;
public:
    test(size_t n) : array(new int[n]), size(n)
    {
        for (int i = 0; i < n; i++) { array[i] = i; }
    }
    ~test() { delete [] array; }
    int* begin() { return array; }
    int* end() { return array + size; }
};

int main()
{
    test T(10);
    for (auto& i : T) {
        std::cout << i;   // prints 0123456789
    }
}

There is no such a possibility in C++03. However new standard (C++11) does have it. See example (taken from Wikipedia):

int my_array[5] = {1, 2, 3, 4, 5};
for (int &x : my_array) {
    x *= 2;
}

Consider also using std::vector<int> instead of an ordinary array. This is C++ analogy for C data types, which makes life easier.


Yes and no.

1. Local array: No, but you can easily find the size

If you have a local array (int numbers[4] = {1, 2, 3, 4];) then you can do size = sizeof(numbers) / sizeof(int).

2. Pointer to array: Not at all, you have to pass the size around separately

If you have a pointer to an array (int* numbers = new int[4];) then you can't figure out the size unless you keep track of it yourself. (or if it's null terminated in the case of a c string, but then you have to iterate through it which is linear running time...)

Note that I don't believe pointer to array is the proper terminology, really you just have a pointer to the first element of the array but space for multiple values has been allocated. Not sure what this is called. Maybe just a pointer?

3. STL containers: Yes, and you can do some for loop magic using iterators, or just use indices by getting the size

If you have a vector (std::vector<int> v(3, 0);) then you can iterate through it the following ways:

C++11:

auto it = v.begin();
for (auto it = v.begin(); it != v.end(); it++)
{
    UseElement(*it);
}

Or apparently (also C++11, thanks jrok):

for (const int& i : v) { UseElement(i); }

C++ (pre-11):

std::vector<int>::iterator it;
for (it = v.begin(); it != v.end(); it++)
{
    UseElement(*it);
}

Or using indices:

for (int i = 0; i < v.size(); i++)
{
    UseElement(v[i]);
}

Furthermore, you can use function pointers or functors with STL containers using std algorithm's for_each (#include <algorithm>) like so:

void foo(int i)
{
    std::cout << i;
}

{
    std::for_each(myvector.begin(), myvector.end(), foo);
}