Macro for an iterator loop for STL iterations

Concept

So I'm trying to define a macro to simplify the following code:

for (vector<TYPE>::iterator iter = iterable.begin(); iter != iterable.end(); iter++) 

and

 for (map<TYPE, TYPE>::iterator iter = iterable.begin(); iter != iterable.end(); iter++) 

and etc.

Existing work

I still have

 #define every(iter, iterable) ::iterator iter = iterable.begin(); iter != iterable.end(); iter++ for (vector<TYPE> every(iter, iterable)) 

but I would like to simplify this further.

purpose

Ideally, I would like to be able to do

 for (every(iter, iterable)) 

which means that I need to somehow get the class<TYPE> iterable object. Is it possible? If so, how can I do this?

CONDITIONS

  • This, ideally, you need to go into a (relatively) large code base already configured to access the iterator object.
  • I am running pre-C ++ 11 compiler

Victory

 #define every(iter, iterable) typeof(iterable.begin()) iter = iterable.begin(); iter != iterable.end(); iter++ for (every(iter, iterable)) 
+7
source share
6 answers

This answer is independent of C ++ 11, but it needs typeof , which some compilers may not have. Should work with any latest g ++

 #define For(iter, iterable) for(typeof((iterable).begin()) iter = (iterable).begin(); iter != (iterable).end(); ++iter) 
+8
source

You can use for(auto iter = iterable.being(); iter != iterable.end(); iter++) if your compiler supports C ++ 0x.

+2
source

If you are using C ++ 11, you can use the new for syntax.

 vector<double> v(9, 0.5); auto total = 0.; for (auto x: v) { total += x; } 

If you need a link to change the values, you can use:

 vector<double> v(9, 0.5); for (auto &x: v) { x = 5; } 

Just compile the flag -std = C ++ 0x.

+2
source

If you are using C ++ 11, use auto!

 for (auto it = vec.begin(); it != vec.end(); it++) { } 

edit:

This will be your macro:

 #define every(iter, iterable) auto iter = iterable.begin(); iter != iterable.end(); iter++ 

Then the implication:

 for(every(iter, iterable)) { UseElement(*iter); } 
+1
source

Why not just use std :: for_each? In C ++ 11, you can use them with lambdas.

C ++ 11 also has a base range loop.

 template<typename T> void Foo(const T& x) { for (auto& i : x) std::cout << i << std::endl; } 

Of course, a must ... MACRO EVIL

If you are stuck in an ancient compiler, you can always do

 typedef std::map<int,int> IntMap_t; IntMap_t tmap; for( IntMap_t::iterator iter = tmap.begin(); iter != tmap.end(); ++iter) { } 
0
source

I would like to extend Aaron McDaid a pretty good answer. I found a very similar solution in a pre-C ++ 0x environment (I named the macro as FOREACH ). It works for regular iterator and reverse iterator . But how can this be done on const_iterator and const_reverse_iterator ? Unfortunately, cbegin() is a C ++ 0x function, and typeof(container)::const_iterator does not work. A very small class of templates can solve the problem. Here is my code:

 template <class T> struct IterType { typedef typename T::const_iterator citer_t; }; #define FOREACHCONST(_CIter, _Container) \ for(IterType<typeof(_Container)>::citer_t _CIter = (_Container).begin(); \ _CIter != (_Container).end(); ++_CIter ) 

It works exactly like FOREACH .

Interestingly, this does not work inside a templated function. In this case, the typename keyword should be added immediately before IterType , but in this case it cannot be used outside the template function.

0
source

All Articles