Pergunta

Como definir todos os valores em um std::map para o mesmo valor, sem usar um loop iteração sobre cada valor?

Foi útil?

Solução

C ++ tem o método fill de <algorithm> mas isso não funciona para mapas. Na verdade, o algoritmo de suporte para recipientes associativas geralmente não é bom.

Como resultado, você terá que usar uma interação ou escrever um functor apropriado para ser usado com for_each (mas eu considero que isso seja sobrecarga desnecessária):

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

Outras dicas

Eu encontrei o mesmo problema, mas descobriu que o intervalo retornado por boost :: adaptadores :: valores é mutável, por isso, em seguida, pode ser utilizado com algoritmos normais, como std :: preenchimento.

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

O boost :: assign biblioteca tem todos os tipos de coisas legais para ajudar a inicializar o conteúdo de um recipiente. Meu pensamento que isso poderia ser usado para evitar explicitamente iteração através do mapa. Infelizmente, os mapas são animais curiosos difícil para inicializar porque as chaves deve ser exclusivo. A linha inferior é que um simples loop for é provavelmente a melhor maneira de inicializar um mapa. Pode não ser super elegante, mas ele começa o trabalho feito e é imediatamente compreensível por qualquer pessoa com qualquer familiaridade com o STL.

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

O resto deste post descreve a viagem que levou para chegar à conclusão acima.

Os boost :: assign torna simples para atribuir um pequeno número de valores a um mapa.

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

ou

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

No seu caso, onde você quer inicializar o mapa inteiro com o mesmo valor, há os utilitários repetir e repeat_fun.
Algo como isso deve funcionar com um multimap (trecho de código não testado)

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

Como Konrad Rudolph como fora pontas, você não pode inicializar um mapa com o mesmo valor exato, porque as chaves deve ser exclusivo.

Isto torna a vida muito mais complexo (diversão?) Mais. Algo como isto, talvez:

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

Agora, isso está ficando tão complexo, agora eu acho que uma iteração simples é o caminho a percorrer

map <int,string> myMap;
for( int k=0;k<1000;k++)
  myMap.insert(pair<int,string>(k,string("")));
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top