如何使用基于范围的 for 循环修改地图中的值?
Posted
技术标签:
【中文标题】如何使用基于范围的 for 循环修改地图中的值?【英文标题】:How can I modify values in a map using range based for loop? 【发布时间】:2015-10-26 00:30:48 【问题描述】:我有一个基于范围的 for 循环来遍历 foobar
中的元素,如下所示:
#include <map>
#include <iostream>
int main()
std::map<int, int> foobar(1,1, 2,2, 3,3);
for(auto p : foobar)
++p.second;
std::cout << "" << p.first << ", " << p.second << " ";
std::cout << std::endl;
for(auto q : foobar)
std::cout << "" << q.first << ", " << q.second << " ";
std::cout << std::endl;
此代码产生以下输出:
1, 2 2, 3 3, 4
1, 1 2, 2 3, 3
第一行在 for 循环中被修改和打印,第二行应该打印相同的修改值。为什么输出不匹配?对std::map
的更改是否仅在循环范围内有效?有没有办法我不仅可以访问而且可以修改这些值?
running version of this code 可以在 cpp.sh 上找到。
编辑:为了清楚起见,修改了此处给出的示例以匹配接受的答案。
【问题讨论】:
【参考方案1】:如果你想改变/修改容器,你可以把auto
变成auto&
,例如:
#include <map>
#include <iostream>
int main()
std::map<int, int> foobar(1,1, 2,2, 3,3);
for(auto& p : foobar)
++p.second;
std::cout << '' << p.first << ", " << p.second << " ";
std::cout << std::endl;
编译并输出
1, 2 2, 3 3, 4live example
【讨论】:
【参考方案2】:Plain auto
是按价值计算的(你会得到一份副本)。使用auto&
。
【讨论】:
【参考方案3】:请注意,从 C++17 开始,您可以使用 结构化绑定:
for (auto & [key, value] : foobar)
std::cout << "" << key << ", " << ++value << " ";
我喜欢这种机制,因为 key
和 value
对于地图的可读性比 p.first
和 p.second
的可读性强。
【讨论】:
【参考方案4】:使用auto
关键字将每个值的副本发送到循环中。如果你想改变地图中的原始值,你需要使用auto&
。
【讨论】:
“当使用for(auto val : myMap)
对val.second
执行的操作是只读的。” 这不是真的。
您被“允许”修改这些值。只是在您的原始代码中,您改为修改 一些其他值(原始值的副本)。没有什么是“只读的”。你看到其他答案了吗?以上是关于如何使用基于范围的 for 循环修改地图中的值?的主要内容,如果未能解决你的问题,请参考以下文章
C++11使用auto关键字进行基于范围的for循环,引用符号&的作用