如何遍历/迭代STL Map?

ato*_*erz 34 c++ dictionary stl traversal

需要知道如何遍历stl地图.我不想用它的钥匙.我不关心排序,只是一种访问它包含的所有元素的方法.有没有办法做到这一点?

Joh*_*ing 61

是的,您可以遍历标准库map.这是用于遍历a的基本方法map,并作为遍历任何标准库集合的指导:

C++ 03/C++ 11:

#include <cstdlib>
#include <map>
#include <string>
using namespace std;

int main()
{
    typedef map<int,string> MyMap;
    MyMap my_map;
    // ... magic

    for( MyMap::const_iterator it = my_map.begin(); it != my_map.end(); ++it )
    {
      int key = it->first;
      string value = it->second;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您需要修改元素:

  • 使用iterator而不是const_iterator.
  • 而不是从迭代器中复制值,获取引用并通过它修改值.

    for(MyMap :: iterator it = my_map.begin(); it!= my_map.end(); ++ it){int key = it-> first; string&value = it-> second; if(value =="foo")value ="bar"; }

这就是您通常手动遍历标准库容器的方式.最大的区别是,对于一个map类型*it是一个pair,而不是元素本身

C++ 11

如果您拥有C++ 11编译器的好处(例如,最新的GCC --std=c++11或MSVC),那么您还有其他选项.

首先,您可以使用auto关键字来摆脱所有令人讨厌的冗长:

#include <cstdlib>
#include <map>
#include <string>
using namespace std;

int main()
{
    map<int,string> my_map;
    // ... magic

    for( auto it = my_map.begin(); it != my_map.end(); ++it )
    {
      int key = it->first;
      string& value = it->second;
    }
}
Run Code Online (Sandbox Code Playgroud)

其次,你也可以雇用lambdas.与此同时decltype,这可能会导致更清晰的代码(尽管有权衡):

#include <cstdlib>
#include <map>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    map<int,string> my_map;
    // ... magic

    for_each(my_map.begin(), my_map.end(), [](decltype(*my_map.begin()) val)
    {
        string& value = val.second;
        int key = val.first;
    });
}
Run Code Online (Sandbox Code Playgroud)

C++ 11还引入了基于范围的for循环的概念,您可能会认为它与其他语言类似.但是,一些编译器还没有完全支持这一点 - 特别是MSVC.

#include <cstdlib>
#include <map>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    map<int,string> my_map;
    // ... magic

    for(auto val : my_map )
    {
        string& value = val.second;
        int key = val.first;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 您继续将值从迭代器中复制出来.您应该使用引用,然后允许操作地图中的数据.`string&value = val.second;`我认为操纵该值的任何(普通)用户都希望地图的内部表示发生变化. (3认同)

fre*_*low 11

与任何STL容器一样,begin()end()方法返回可用于迭代地图的迭代器.取消引用映射迭代器会产生一个std::pair<const Key, Value>.


hon*_*onk 7

C++17

C++17 开始,您可以使用基于范围的 for 循环结构化绑定来迭代映射。生成的代码(例如用于打印地图的所有元素)简短且易读:

std::map<int, std::string> m{ {3, "a"}, {5, "b"}, {9, "c"} };

for (const auto &[k, v] : m)
    std::cout << "m[" << k << "] = " << v << std::endl;
Run Code Online (Sandbox Code Playgroud)

输出:

m[3] = a
m[5] = b
m[9] = c

Coliru 上的代码


vit*_*aut 5

您可以使用与任何其他STL容器相同的方式遍历STL映射:使用迭代器,例如

for (std::map<key, value>::const_iterator
     i = myMap.begin(), end = myMap.end(); i != end; ++i)
{
    // *i is a key-value pair
}
Run Code Online (Sandbox Code Playgroud)