Domanda

Ho codice che appare sostanzialmente in questo modo:

std::map<int, int> map1, map2;
BOOST_FOREACH(int i, map1)
{
    // do steps 1-5 here...
}
BOOST_FOREACH(int i, map2)
{
    // do steps 1-5 (identical to above) here...
}

C'è un modo per concatenare le mappe per eliminare il codice duplicato nel secondo ciclo? O un modo per estendere BOOST_FOREACH per scorrere su due mappe diverse in una volta sola? Ovviamente non voglio aumentare la complessità temporale del programma (altrimenti potrei semplicemente creare una nuova mappa e inserire in esso map1 e MAP2). Ho la sensazione che mi manca qualcosa qui rudimentale.

È stato utile?

Soluzione

Si potrebbe definire una funzione:

typedef std::map<int, int> IntMap;

void doStuffWithInt(IntMap::value_type &i)
{
  // steps 1 to 5
}

BOOST_FOREACH(IntMap::value_type &i, map1)
  doStuffWithInt(i);
BOOST_FOREACH(IntMap::value_type &i, map2)
  doStuffWithInt(i);

Anche se in questo caso potrebbe essere ancora più semplice da usare std::for_each:

for_each(map1.begin(), map1.end(), doStuffWithInt);
for_each(map2.begin(), map2.end(), doStuffWithInt);

Altri suggerimenti

L'idea è di scrivere un tipo speciale di iteratori praticamente unire due contenitori, per quanto concerne BOOST_FOREACH. Si noti che non sto creando un nuovo contenitore fuori delle due esistenti. Sto semplicemente saltando dalla fine del primo contenitore () per iniziare () iteratore del secondo contenitore. Non ho provato e scrivo la classe merged_iterator reale, ma anche se potrebbe un po 'tempo per scrivere, non è tecnicamente difficile. Sono davvero sorpreso di non aver trovato qualcosa di simile utilizzando Google. Non ho guardato a lungo, però!

template<typename Container>
boost::iterator_range<
  merged_iterator<Container::iterator>
  >
concat_containers( Container& c1, Container& c2 )
{
  typedef merged_iterator<typename Container::iterator> MergedIterator;
  typedef boost::iterator_range<MergedIterator> IteratorRange;
  return IteratorRange(
    MergeIterator( c1.begin(), c1.end(), c2.begin(), c2.end() ),
    MergeIterator( c2.end(), c1.end(), c2.begin(), c2.end() ) );
}

// Now use a bit of magic to define merged_iterator<...>
// And you'll be able to write

BOOST_FOREACH( std::pair<int, int> i, concat_containers( map1, map2 ) )
{
// Do whatever you want here
}

Oltre alla soluzione del 1800, che vi consiglio vivamente, ci sono anche diverse soluzioni hacky:

for (int stage = 0; stage < 2; stage++) {
    BOOST_FOREACH(int i, stage == 0 ? map1 : map2) {
        ...
    }
}

typedef std::map<int, int> intmap;
std::vector<intmap *> v;
v.push_back(&map1);
v.push_back(&map2);
BOOST_FOREACH(intmap *m, v) {
    BOOST_FOREACH(int i, *m) {
        ...
    }
}

Nota: quando vedo colleghi scrivono il codice come questo, a volte io sono preso da una voglia irresistibile di andare loro strangolare. Utilizzare a proprio rischio.

Il modo più semplice è come questo:

std::map<int, int> map1, map2;
int key, value;
BOOST_FOREACH(boost::tie(key, value), boost::join(map1, map2))
{
    // do steps 1-5 here...
}

E non preoccupatevi quelle virgole non confondere il preprocessore a causa della parentesi.

della parte superiore della mia testa, mi piacerebbe provare

std::map<int, int> map1, map2;
std::map<int, int>& maps = { map1, map2 }
BOOST_FOREACH(std::map<int, int> map, maps)
  BOOST_FOREACH(int i, map)
  {
      // do steps 1-5 here...
  }

E 'spiegato qui .

Si può fare questo:

std::map<int,int> m;
typedef std::pair<int,int> pair_t;
BOOST_FOREACH(pair_t p, m)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top