如何在不使用循环迭代每个值的情况下将
std::map
中的所有值设置为相同的值?使用循环是最简单的方法。实际上,这只需要一行代码:[C++17]
for (auto& [_, v] : mymap) v = value;
很遗憾,在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);
#include <boost/range/adaptor/map.hpp>
auto my_values = boost::adaptors::values(my_map);
std::fill(my_values.begin(), my_values.end(), 123);
boost::assign库有很多有用的东西来帮助初始化容器。我认为这可以用来避免显式地迭代map。不幸的是,map是一种奇怪的动物,因为键必须是唯一的,所以很难初始化。总之,一个简单的for循环可能是初始化map的最佳方式。它可能不是非常优雅,但它能完成任务,并且任何熟悉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工具。
以下代码片段应该适用于multimap(未经测试)
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("")));
map
并不是以哈希表实现的。 - Konrad Rudolph