Установка всех значений в std :: map - PullRequest
6 голосов
/ 26 сентября 2008

Как установить все значения в std::map на одно и то же значение, не используя цикл, повторяющийся над каждым значением?

Ответы [ 3 ]

13 голосов
/ 26 сентября 2008

C ++ имеет метод fill из <algorithm>, но это не работает для карт. На самом деле, поддержка алгоритмов для ассоциативных контейнеров, как правило, не очень хорошая.

В результате вам придется использовать целочисленное значение или написать соответствующий функтор для использования с for_each (но я считаю, что это ненужные накладные расходы):

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));
3 голосов
/ 22 июня 2015

Я столкнулся с той же проблемой, но обнаружил, что диапазон, возвращаемый boost :: adapters :: values, является изменчивым, поэтому его можно использовать с обычными алгоритмами, такими как 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);
2 голосов
/ 26 сентября 2008

В библиотеке boost :: assign есть много полезных вещей, помогающих инициализировать содержимое контейнера. Я думал, что это можно использовать, чтобы избежать явных итераций по карте. К сожалению, карты являются любопытными зверями, которые трудно инициализировать, потому что ключи должны быть уникальными. Суть в том, что простой цикл for - это, вероятно, лучший способ инициализации карты. Это может быть не очень изящно, но оно выполняет свою работу и сразу же понятно любому, кто знаком с STL.

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

Остальная часть этого поста описывает путешествие, которое я предпринял, чтобы прийти к вышеуказанному выводу.

Функция boost :: assign упрощает назначение небольшого числа значений карте.

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

или

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

В вашем случае, когда вы хотите инициализировать всю карту с тем же значением, есть утилиты repeat и repeat_fun.
Примерно так должно работать с мультикартой (фрагмент кода непроверенного)

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

Как указал Конрад Рудольф, вы не можете инициализировать карту с таким же точным значением, потому что ключи должны быть уникальными.

Это делает жизнь намного сложнее (весело?). Возможно, что-то вроде этого:

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

Теперь, это становится настолько сложным, теперь я думаю, что простая итерация - это путь

map <int,string> myMap;
for( int k=0;k<1000;k++)
  myMap.insert(pair<int,string>(k,string("")));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...