Domanda

Come impostare tutti i valori in std::map sullo stesso valore, senza utilizzare un ciclo che scorre su ogni valore?

È stato utile?

Soluzione

C ++ ha il metodo fill da <algorithm> ma questo non funziona per le mappe. In effetti, il supporto dell'algoritmo per i contenitori associativi non è generalmente buono.

Di conseguenza, dovrai utilizzare un'interazione o scrivere un funzione appropriata da utilizzare con for_each (ma considero questo un sovraccarico non necessario):

template <typename TKey, typename TValue>
struct resetter : public std::unary_function<std::pair<TKey, TValue> > {
    TValue const value;

    public resetter(value const& v) : value(v) { }

    public void operator ()(std::pair<TKey, TValue>& v) {
        v.second = value;
    }
};

for_each(map.begin(), map.end(), resetter<Key, Value>(value));

Altri suggerimenti

Ho riscontrato lo stesso problema, ma ho scoperto che l'intervallo restituito da boost :: adattatori :: valori è mutabile, quindi può essere utilizzato con algoritmi normali come std :: fill.

#include <boost/range/adaptor/map.hpp>
auto my_values = boost::adaptors::values(my_map);
std::fill(my_values.begin(), my_values.end(), 123);

La libreria boost :: assegnare ha ogni sorta di roba ordinata per aiutare a inizializzare il contenuto di un contenitore. Ho pensato che questo potesse essere usato per evitare di scorrere esplicitamente la mappa. Sfortunatamente, le mappe sono animali curiosi difficili da inizializzare perché le chiavi devono essere uniche. La linea di fondo è che un semplice ciclo per è probabilmente il modo migliore per inizializzare una mappa. Potrebbe non essere super elegante, ma svolge il lavoro ed è immediatamente comprensibile da chiunque abbia qualche conoscenza con la STL.

map <int,string> myMap;
for( int k=0;k<1000;k++)
  myMap.insert(pair<int,string>(k,string("")));

Il resto di questo post descrive il viaggio che ho fatto per raggiungere la conclusione di cui sopra.

boost :: assegn semplifica l'assegnazione di un piccolo numero di valori a una mappa.

map<string,int> m; 
insert( m )( "Bar", 1 )( "Foo", 2 );

o

 map<int,int> next = map_list_of(1,2)(2,3)(3,4)(4,5)(5,6);

Nel tuo caso, dove vuoi inizializzare l'intera mappa con lo stesso valore, ci sono le utility repeat e repeat_fun.
Qualcosa del genere dovrebbe funzionare con una multimap (snippet di codice non testato)

pair<int,string> init( 0,string(""));
multimap <int,string> myMap = repeat(1000,init);

Come sottolineato da Konrad Rudolph, non è possibile inizializzare una mappa con lo stesso valore esatto, poiché le chiavi devono essere univoche.

Questo rende la vita molto più complessa (divertente?). Qualcosa del genere, forse:

map <int,string> myMap;

struct nextkey
{
   int start;
   nextkey( s ) : start( s ) {}
   pair<int,string> operator () ()
{
   return pair<int,string>(start++,string(""));
}
};

myMap = repeat_fun(1000,nextkey(0));

Ora, questo sta diventando così complesso, ora penso che una semplice iterazione sia la strada da percorrere

<*>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top