Pregunta

Cómo configurar todos los valores en un std::map al mismo valor, sin utilizar un bucle que itera sobre cada valor?

¿Fue útil?

Solución

C ++ tiene el método fill de <algorithm> pero esto no funciona para los mapas. De hecho, el soporte de algoritmos para contenedores asociativos generalmente no es bueno.

Como resultado, tendrá que usar una interacción o escribir un functor apropiado para usar con for_each (pero considero que esto es una sobrecarga innecesaria):

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));

Otros consejos

Encontré el mismo problema pero descubrí que el rango devuelto por boost::adaptors::values ​​es mutable, por lo que puede usarse con algoritmos normales como 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 biblioteca boost :: asignar tiene todo tipo de cosas ordenadas para ayudar a inicializar el contenido de un contenedor. Pensé que esto podría usarse para evitar iterar explícitamente a través del mapa. Desafortunadamente, los mapas son bestias curiosas difíciles de inicializar porque las claves deben ser únicas. La conclusión es que un bucle simple es probablemente la mejor manera de inicializar un mapa. Puede que no sea súper elegante, pero hace el trabajo y es inmediatamente comprensible para cualquiera que conozca el STL.

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

El resto de esta publicación describe el viaje que hice para llegar a la conclusión anterior.

El boost :: asignar simplifica la asignación de una pequeña cantidad de valores a un mapa.

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);

En su caso, donde desea inicializar todo el mapa con el mismo valor, están las utilidades repeat y repeat_fun.
Algo como esto debería funcionar con un mapa múltiple (fragmento de código no probado)

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

Como Konrad Rudolph señaló, no puede inicializar un mapa con el mismo valor exacto, porque las claves deben ser únicas.

Esto hace que la vida sea mucho más compleja (¿divertida?). Algo como esto, tal vez:

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));

Ahora, esto se está volviendo tan complejo, ahora creo que una simple iteración ES el camino a seguir

<*>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top