C++ 使用索引for循环在无序映射上迭代
我试图使用C++ 使用索引for循环在无序映射上迭代,c++,hashtable,unordered-map,C++,Hashtable,Unordered Map,我试图使用for循环访问存储在中的值,但我无法使用循环的当前索引访问值。有什么建议或链接可以查看吗?谢谢[提示:我不想使用迭代器] 我的示例代码: #include <iostream> #include <string> #include <unordered_map> #include <vector> using namespace std; int main() { unordered_map<int,string>h
for循环访问存储在中的值,但我无法使用循环的当前索引访问值。有什么建议或链接可以查看吗?谢谢[提示:我不想使用迭代器]
我的示例代码:
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
int main()
{
unordered_map<int,string>hash_table;
//filling my hash table
hash_table.insert(make_pair(1,"one"));
hash_table.insert(make_pair(2,"two"));
hash_table.insert(make_pair(3,"three"));
hash_table.insert(make_pair(4,"four"));
//now, i want to access values of my hash_table with for loop, `i` as index.
//
for (int i=0;i<hash_table.size();i++ )
{
cout<<"Value at index "<<i<<" is "<<hash_table[i].second;//I want to do something like this. I don't want to use iterator!
}
return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main()
{
无序映射哈希表;
//填充我的哈希表
哈希表。插入(组成一对(1,“一”);
hash_表.insert(生成一对(2,“两”);
散列表。插入(组成一对(3,“三”);
hash_表。insert(组成一对(4,“4”);
//现在,我想使用for循环'i'作为索引来访问我的hash_表的值。
//
对于(int i=0;i,没有迭代器就无法完成。无序映射可以按任意顺序存储内容并随意移动。例如,“第三元素”的概念没有任何意义
如果你有一个来自映射的键列表,那么你可以索引到该键列表中并得到你想要的。但是,除非你已经有了它,否则你需要在映射上迭代以生成键列表,因此你仍然需要一个迭代器。有两种方法可以从std::unordered\u映射
访问元素
迭代器
下标运算符,使用键
我无法使用循环的当前索引访问值
正如您所看到的,使用索引访问元素并没有在访问元素的可能方式中列出
我确信您已经意识到,由于映射是无序的,索引I
处的短语元素在排序方面是毫无意义的。可以使用begin
迭代器和std::advance
访问I
th元素,但是
提示:我不想使用迭代器]
提示:您已经没有选择了。您想做的是不可能的。解决方案:开始使用适合实现目标的工具
如果要迭代std::unordered_map
,则使用迭代器,因为这就是迭代器的用途。如果不想使用迭代器,则无法迭代std::unordered_map
。可以使用基于范围的for循环隐藏迭代器的使用,但它们仍在幕后使用
如果您想使用位置索引来迭代某些内容,那么您需要的是一个数组,例如std::vector
,首先,为什么要使用索引而不是迭代器呢?
假设您有一个希望UI绘制的小部件列表。每个小部件都可以有自己的子小部件列表,存储在地图中。您的选项有:
让每个小部件自己绘制。这并不理想,因为小部件现在与您正在使用的UI工具包耦合
返回映射并在绘图代码中使用迭代器。这并不理想,因为现在绘图代码知道了您的存储机制
可以避免这两种情况的API可能如下所示
const小部件*小部件::枚举子项(大小*io索引)const;
您可以使用映射进行此操作,但效率不高。您也无法保证调用之间映射的稳定性。因此,不建议这样做,但这是可能的
您不必使用std::advance,也可以自己使用for循环来提升迭代器。这既不高效也不安全
对于我描述的场景,更好的解决方案是将值复制到向量中
void Widget::GetChildren(std::vector<Widget*>* o_children) const;
void小部件::GetChildren(std::vector*o_children)const;
一个老问题
好吧,我在冒险:这里可能有一个解决办法(虽然不是完美的:它只是一个解决办法)
这篇文章有点长,因为我解释了为什么可能需要这样做。事实上,人们可能希望使用非常相同的代码从文件加载和保存数据。这对于同步数据的加载和保存、保持相同的数据、相同的顺序和相同的类型非常有用
例如,如果op是load_op或save_op:
load_save_data( var1, op );
load_save_data( var2, op );
load_save_data( var3, op );
...
load_save_数据隐藏了内部执行的操作。因此,维护更加容易
问题是当涉及到容器时。例如(回到问题),它可能会对集合(源A)执行此操作以保存数据:
int thesize = theset.size();
load_save(thesize, load); // template (member) function with 1st arg being a typename
for( elem: theset) {
load_save_data( thesize, save_op );
}
但是,要读取(源B):
intthesize;
加载保存数据(大小,保存);
对于(int i=0;iYou不能只对std::unordered_map
(或std::map
)使用普通数组索引,因为操作符[]
函数需要一个键而不是索引。因此,您希望在[1,4]中进行迭代
。如果要将映射中的元素添加到数组中,可能您只需要一个std::vector
通过索引循环是很方便的。为什么?因为Firecode希望我返回数组。
int thesize = theset.size();
load_save(thesize, load); // template (member) function with 1st arg being a typename
for( elem: theset) {
load_save_data( thesize, save_op );
}
int thesize;
load_save_data( thesize, save);
for( int i=0; i<thesize, i++) {
Elem elem;
load_save_data( elem, load_op);
theset.insert(elem);
}
int thesize;
load_save_data( thesize, save);
for( int i=0; i<thesize, i++) {
Elem elem;
if( op == save_op ) {
elem=theset[i]; // not possible
}
load_save_data( elem, op);
if( op == load_op ) {
theset.insert(elem);
}
}
void ...::load_save( op )
{
...
int thesize;
set<...> tmp;
load_save_data( thesize, save);
for( int i=0; i<thesize, i++) {
Elem elem;
if( op == save_op ) {
elem=*(theset.begin()); \
theset.erase(elem); > <-----
tmp.insert(elem); /
}
load_save_data( elem, op);
if( op == load_op ) {
theset.insert(elem);
}
}
if(op == save_op) {
theset.insert(tmp.begin(), tmp.end()); <-----
}
...
}