在 std::map 中设置所有值
Setting all values in a std::map
如何在不使用循环迭代每个值的情况下将std::map
中的所有值设置为相同的值?
使用循环是迄今为止最简单的方法。事实上,这是一个单行:[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::adaptors::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);
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_fun。
这样的东西应该适用于多映射(未经测试的代码片段)
pair<int,string> init( 0,string(""));
multimap <int,string> myMap = repeat(1000,init);
正如康拉德·鲁道夫(Konrad Rudolph)所指出的,您不能使用相同的精确值初始化映射,因为键必须是唯一的。
这使得生活变得更加复杂(有趣? 像这样的东西,也许:
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("")));
- 按索引设置 std::variant 的值
- 为什么不能通过在错误输入后设置 std::cin.clear() 来使用 std::cin?
- 如何取消设置 std::cout 精度?
- 如何使用 gdb 设置 std::map 变量
- 如何在C++中设置std::list参数的默认值?
- C 设置STD :: MAP值为结构实例的指针
- C++ 在标准::unordered_map中设置 std::tuple 值
- 我可以在 c++ 中正确设置 std::vector by operator[] 的第 n 个值吗?
- 设置 std::function 变量以引用 std::sin 函数
- ISO C++禁止声明 .没有设置 --std=c++0x 的类型
- 使用printf样式的格式设置std::字符串的内容
- 如何设置std::vector的初始大小
- 在类构造函数中设置 std::vector
- 如何在 eclipse makefile 项目中的编译器选项中设置 -std=c++0x
- 尝试通过CGAL_CXX_FLAGS设置 --std=c++0x 或 -std=gnu++0x 会忽略值
- 有没有更有效的方法从流中设置 std::vector
- 在 C++11 中设置 std::线程优先级的便携式方法
- 直接使用运算符[]设置std::vector内容
- 如何使用 std::imbue 来设置 std::wcout 的区域设置
- 如何设置' std::exponential_distribution '对象的参数