views:

299

answers:

3

You can simulate foreach-statement in c++ with macro declaration. I'm using similar syntax for looping arrays in the following way:

int array1[10];
vector<int> array2(10);

fori(array1)
    forj(array2)
        fork(123)
             if(array1[i]==array[j])
                  return true;

What's your favorite macros for extending c++ language in some way?

EDIT:

Implementation of the macro mentioned in the question is:

#define fori(a) for(int i=0;i<getsize(a);i++)
#define forj(a) for(int j=0;j<getsize(a);j++)
#define foru(a) for(int u=0;u<getsize(a);u++)
#define fork(a) for(int k=0;k<getsize(a);k++)
#define forl(a) for(int l=0;l<getsize(a);l++)

template<typename T>
int getsize(T& v ){return v.size();}
template<typename T,int N>
int getsize(T(&v)[N]){return N;}
int getsize(int v){return v;}
+7  A: 

You should check out Boost.Foreach.

vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
BOOST_FOREACH(int& i, v)
{
    i = i * i;
}
rlbond
Yes, but is it usable? Are you using it in your code?
AareP
Well you're using your own version aren't you? Yes, Boost.Foreach works very well.
GMan
Yeah, it's great for writing fast, understandable code. Much better than the macro you're using.
rlbond
Plus it works with any container or a regular c-array.
rlbond
i love it. BOOST_FOREACH, boost::function and boost::shared_ptr << never wanna miss you!
Johannes Schaub - litb
+1. Boost foreach is neat. You may already be aware but your example would benefit from boost assign too! v += 1, 2 ,3, 4, 5;
MattyT
The only thing I hate about boost foreach is it's too loud in the morning shouting like that.
Martin York
BOOOOOST! FOOOOR! EEEEEEEEAAAAAACH!!!
AareP
+1  A: 

If for some reason I need to skip STL containers I use this macro for my container classes:

#define M_foreach( iterable ) \
do {\
  (iterable).prepareit();\
  while (  (iterable).stepit()  ) {

#if !defined( M_end )
#  define M_end   } } while( 0 );
#endif

(that macro assumes that you use a container that has an iteration interface)

Container foo;
M_foreach ( foo )
   ...
   Container bar;
   M_foreach ( bar )
      ...
   M_end
   ...
M_end
Nick D
Very Java like.
Martin York
A: 

I find boost's macro a bit cumbersome.

Here's my attempt:

#include <boost/typeof/typeof.hpp>
#define FOR_EACH(cont, iter)    \   
  for (BOOST_TYPEOF(cont)::const_iterator iter = cont.begin(), e = cont.end(); \
    iter != e; \
    ++iter)

Works for standard containers.

Used like so:

vector<int> vi;
// ...
FOR_EACH(vi, i)
  cout << *i;

Supports nesting:

map<string, list<int> > msli;
msli["key1"].push_back(1);
msli["key1"].push_back(2);
msli["key2"].push_back(3);
msli["key2"].push_back(4);

FOR_EACH(msli, i) {
  cout << i->first << endl;
  FOR_EACH(i->second, j)
    cout << "\t" << *j << endl;
}

/*
Prints:
  key1
    1
    2
  key2
    3
    4
*/

Source: http:/wtw.tw/papers/foreach.html

Assaf Lavie