web-dev-qa-db-fra.com

en utilisant BOOST_FOREACH avec std :: map

Je voudrais parcourir une carte std :: en utilisant BOOST_FOREACH et modifier les valeurs. Je ne peux pas vraiment l'obtenir.

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

Bien sûr, cela ne change rien car je n'itère pas par référence. Je remplace donc cette ligne à la place (selon l'exemple dans les documents Boost):

BOOST_FOREACH( IdSizePair_t &i, mmap )

et j'obtiens l'erreur du compilateur:

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

Aucune suggestion?

45
kmote

Le problème vient du premier membre de la paire, qui devrait être const. Essaye ça:

typedef std::map<int, int> map_t;
map_t mmap;  
BOOST_FOREACH( map_t::value_type &i, mmap )
    i.second++;
68
hvintus

Il s'agit d'un ancien fil, mais il existe une solution plus pratique.

boost a la notion d '"adaptateurs de plages" qui effectuent une transformation sur les plages d'itérateurs. Il existe des adaptateurs de plage spécifiques pour ce cas d'utilisation exact (itération sur des clés ou des valeurs de carte): boost::adaptors::map_values et boost::adaptors::map_keys.

Vous pouvez donc parcourir les valeurs de carte comme ceci:

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

Plus d'informations ici .

21
Alex Goldberg

Une autre option consiste à utiliser BOOST_FOREACH_PAIR, voir ma réponse ici:

BOOST_FOREACH & modèles sans typedef

4
dtw

Depuis C++ 11, envisagez d'utiliser le mot-clé auto:

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
K.B