【问题标题】:How can I modify values in a map using range based for loop?如何使用基于范围的 for 循环修改地图中的值?
【发布时间】: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 上找到。

编辑:为了清楚起见,修改了此处给出的示例以匹配接受的答案。

【问题讨论】:

    标签: c++ for-loop dictionary


    【解决方案1】:

    如果你想改变/修改容器,你可以把auto变成auto&amp;,例如:

    #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, 4}

    live example

    【讨论】:

      【解决方案2】:

      Plain auto 是按价值计算的(你会得到一份副本)。使用auto&amp;

      【讨论】:

        【解决方案3】:

        请注意,从 C++17 开始,您可以使用 结构化绑定

        for (auto & [key, value] : foobar)
          std::cout << "{" << key << ", " << ++value << "} ";
        

        我喜欢这种机制,因为 keyvalue 对于地图的可读性比 p.firstp.second 的可读性强。

        【讨论】:

          【解决方案4】:

          使用auto 关键字将每个值的副本发送到循环中。如果你想改变地图中的原始值,你需要使用auto&amp;

          【讨论】:

          • “当使用for(auto val : myMap)val.second 执行的操作是只读的。” 这不是真的。
          • ​​​​​​​​​​​您“允许”修改这些值。只是在您的原始代码中,您改为修改 一些其他值(原始值的副本)。没有什么是“只读的”。你看到其他答案了吗?
          猜你喜欢
          • 2018-12-14
          • 2016-10-31
          • 2021-08-25
          • 1970-01-01
          • 2013-01-04
          • 1970-01-01
          • 2015-11-03
          • 2016-04-03
          相关资源
          最近更新 更多