




Использование цикла является на сегодняшний день самый простой метод. Фактически, это однострочный: [C++17]
for (auto& [_, v] : mymap) v = value;
К сожалению, поддержка алгоритмов C++ для ассоциативных контейнеров не очень хороша до C++ 20. Как следствие, мы не можем напрямую использовать std::fill.
Чтобы использовать их в любом случае (до C++ 20), нам нужно написать адаптеры - в случае std::fill, адаптер итератора. Вот минимально жизнеспособная (но не совсем соответствующая) реализация, чтобы проиллюстрировать, сколько усилий это требует. Я же нет советую использовать как есть. Используйте библиотеку (такую как Boost.Iterator) для более общей, производственной реализации.
template <typename M>
struct value_iter : std::iterator<std::bidirectional_iterator_tag, typename M::mapped_type> {
using base_type = std::iterator<std::bidirectional_iterator_tag, typename M::mapped_type>;
using underlying = typename M::iterator;
using typename base_type::value_type;
using typename base_type::reference;
value_iter(underlying i) : i(i) {}
value_iter& operator++() {
++i;
return *this;
}
value_iter operator++(int) {
auto copy = *this;
i++;
return copy;
}
reference operator*() { return i->second; }
bool operator ==(value_iter other) const { return i == other.i; }
bool operator !=(value_iter other) const { return i != other.i; }
private:
underlying i;
};
template <typename M>
auto value_begin(M& map) { return value_iter<M>(map.begin()); }
template <typename M>
auto value_end(M& map) { return value_iter<M>(map.end()); }
При этом мы можем использовать std::fill:
std::fill(value_begin(mymap), value_end(mymap), value);
В библиотеке 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("")));
Ваш фрагмент кода не будет работать на простой карте, потому что вы снова вставляете один и тот же ключ. В этом случае вы должны использовать функцию генератора.
Хорошая точка зрения! Это должна быть мульти-карта или использовать repeat_fun. Интересно, чего хотел исходный вопрос?
Да Boost :: assign - ваше самое простое решение для заполнения карт. Полностью согласен, к тому же синтаксис гладкий, почти как скрипт.
Я столкнулся с той же проблемой, но обнаружил, что диапазон, возвращаемый функцией 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);
Торстен, C++ STL
map- это нет, реализованный в виде хэш-таблицы.