Using BOOST_FOREACH with std :: map

I would like to iterate over std :: map using BOOST_FOREACH and edit the values. I can’t figure it out.

typedef std::pair<int, int> IdSizePair_t; std::map<int,int> mmap; mmap[1] = 1; mmap[2] = 2; mmap[3] = 3; BOOST_FOREACH( IdSizePair_t i, mmap ) i.second++; // mmap should contain {2,3,4} here 

Of course, this does not change anything, because I do not repeat the links. So I will replace this line instead (as per the example in the Boost docs):

 BOOST_FOREACH( IdSizePair_t &i, mmap ) 

and I get a compiler error:

 error C2440: 'initializing' : cannot convert from 'std::pair<_Ty1,_Ty2>' to 'IdSizePair_t &' with [ _Ty1=const int, _Ty2=int ] 

Any suggestions?

+44
c ++ boost foreach std maps
Apr 27 '09 at 21:55
source share
4 answers

The problem is the first member of the pair, which must be const. Try the following:

 typedef std::map<int, int> map_t; map_t mmap; BOOST_FOREACH( map_t::value_type &i, mmap ) i.second++; 
+66
Apr 27 '09 at 22:09
source share

This is an old thread, but there is a more convenient solution.

boost has the concept of "range adapters" that perform conversion on iterator ranges. There are special range adapters for this exact use case (iterating over maps or values): boost::adaptors::map_values and boost::adaptors::map_keys .

So, you can iterate over the values ​​of such maps as follows:

 BOOST_FOREACH(int& size, mmap | boost::adaptors::map_values) { ++size; } 

More details here .

+21
04 Oct
source share

Another option is to use BOOST_FOREACH_PAIR, see my answer here:

BOOST_FOREACH and templates without typedef

+4
Aug 04 '10 at 5:23
source share

With C ++ 11, consider using the auto keyword:

 std::map<int,int> mmap; mmap[1] = 1; mmap[2] = 2; mmap[3] = 3; BOOST_FOREACH(auto& mpair, mmap) mpair.second++; //mmap will contain {2,3,4} here 
0
Aug 17 '15 at 18:44
source share



All Articles