views:

1657

answers:

4

I'd like to iterate over a std::map using BOOST_FOREACH and edit the values. I can't quite get it.

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 doesn't change anything because I'm not iterating by reference. So I substitute this line instead (as per the example in the Boost docs):

BOOST_FOREACH( IdSizePair_t &i, mmap )

and I get the compiler error:

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

Any suggestions?

+11  A: 

The problem is with the first member of the pair, which should be const. Try this:

typedef std::map<int, int> map_t;
map_t mmap;  
BOOST_FOREACH( map_t::value_type &i, mmap )
    i.second++;
hvintus
+1. you beat me by few seconds :D
Johannes Schaub - litb
Thanks, hvint. That did it. Also (after reading your comment) I realized that another way to fix it is to change the first line of my original code to this: typedef std::pair<const int, int> IdSizePair_ty;(which allows me to iterate by reference)
kmote
kmote, yes, actually that is what i proposed in my answer (which i deleted when i saw hvint one's). Also, do you know why it behaves that way? I'll undelete mine if you need some explanation.
Johannes Schaub - litb
A: 

What compiler are you using? I tried your code on VS2008 and it worked correctly. I tested hvint's answer too and it worked.

I'm using boost 1.36, if that matters.

Edison Gustavo Muenz
Johannes Schaub - litb
A: 

When I try hvint's suggestion above,


typedef std::map map_t; map_t mmap;
BOOST_FOREACH( map_t::value_type &i, mmap ) i.second++;


I get a compile error: error C2065: 'i' : undeclared identifier

pnelnik
A: 

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

http://stackoverflow.com/questions/1713653/boost-foreach-templates-without-typedef/1745774#1745774

dtw