C++循环遍历Map

465

我希望能够遍历 map<string, int> 中的每个元素,而不知道任何字符串-整数值或键。

目前我已经有:

void output(map<string, int> table)
{
       map<string, int>::iterator it;
       for (it = table.begin(); it != table.end(); it++)
       {
            //How do I access each element?  
       }
}

4
可能是如何遍历C++ Map的重复问题。 - amanuel2
2
你很可能不想通过值获取地图,最好将其作为const map<string,int>& table获取。 - Amir Kirsh
8个回答

957

您可以像以下方式实现此操作:

map<string, int>::iterator it;

for (it = symbolTable.begin(); it != symbolTable.end(); it++)
{
    std::cout << it->first    // string (key)
              << ':'
              << it->second   // string's value 
              << std::endl;
}

使用C++11(以及以后版本)


for (auto const& x : symbolTable)
{
    std::cout << x.first  // string (key)
              << ':' 
              << x.second // string's value 
              << std::endl;
}

随着C++17(以及之后的版本)

for (auto const& [key, val] : symbolTable)
{
    std::cout << key        // string (key)
              << ':'  
              << val        // string's value
              << std::endl;
}

13
在“it”的前面加上“auto”类型。 - iedoc
5
为什么在C++11中用"auto const&",而在C++17中用"const auto&"?"auto const&"和"const auto&"有什么区别吗? - Eric
67
没什么区别,只是个人口味问题。然而,似乎@P0W的口味不太一致... - Kapichu
33
感谢更新到C++17版本,我一直在寻找auto const& [key, val] : symbolTable的格式! - Water
4
你可能需要在项目设置中设置“ISO C++17标准 (/std:c++17)”(配置属性> C / C ++> 语言> C ++语言标准)。 - Swordfish
显示剩余13条评论

38
尝试以下操作:
for ( const auto &p : table )
{
   std::cout << p.first << '\t' << p.second << std::endl;
} 

可以使用普通的for循环来编写相同的代码。
for ( auto it = table.begin(); it != table.end(); ++it  )
{
   std::cout << it->first << '\t' << it->second << std::endl;
} 

请注意,std::map的value_type定义如下:

typedef pair<const Key, T> value_type

因此,在我的例子中,p是对value_type的常量引用,其中Key是std::string,T是int

另外,如果将函数声明为以下形式,则会更好:

void output( const map<string, int> &table );

14

mapvalue_type 是一个 pair,其中的 firstsecond 成员分别包含了键和值。

map<string, int>::iterator it;
for (it = symbolTable.begin(); it != symbolTable.end(); it++)
{
    std::cout << it->first << ' ' << it->second << '\n';
}

或者使用C++11,使用基于范围的for循环:

for (auto const& p : symbolTable)
{
    std::cout << p.first << ' ' << p.second << '\n';
}

11

正如来自莫斯科的@Vlad所说, 请注意,std::mapvalue_type 是按照以下方式定义的:

typedef pair<const Key, T> value_type

这意味着如果您想用更明确的类型说明符替换关键字auto,则可以这样做:
for ( const pair<const string, int> &p : table ) {
   std::cout << p.first << '\t' << p.second << std::endl;
} 

只是为了理解在这种情况下auto将翻译成什么。


11

由于P0W已经为每个C++版本提供了完整的语法,我想通过查看您的代码添加几个要点:

  • 始终将const &作为参数,以避免多余的对象副本。
  • 使用unordered_map,因为它总是更快。请参见这里的讨论

这是一个示例代码:

#include <iostream>
#include <unordered_map>
using namespace std;

void output(const auto& table)
{
   for (auto const & [k, v] : table)
   {
        std::cout << "Key: " << k << " Value: " << v << std::endl;
   }
}

int main() {
    std::unordered_map<string, int> mydata = {
        {"one", 1},
        {"two", 2},
        {"three", 3}
    };
    output(mydata);
    return 0;
}

如果我们不使用const&,同一对象的多个副本如何被创建?是否存在任何边缘情况可能会发生这种情况? - Ashutosh Tiwari
1
@AshutoshTiwari 这是变量&的引用,它避免了创建多个副本,当我们获取引用时,我们不希望其被修改,因此我们使用const - Mital Vora

3

甚至可以使用经典的for循环来完成。
手动推进迭代器。

typedef std::map<int, int> Map;

Map mymap;

mymap['a']=50;
mymap['b']=100;
mymap['c']=150;
mymap['d']=200;

bool itexist = false;
int sizeMap = static_cast<int>(mymap.size());
auto it = mymap.begin();
for(int i = 0; i < sizeMap; i++){
    std::cout << "Key: " << it->first << " Value: " << it->second << std::endl;
    it++;
}

3

如果您只想迭代内容而不更改值,请执行以下操作:

for(const auto & variable_name : container_name(//here it is map name)){
    cout << variable_name.first << " : " << variable_name.second << endl; 
} 

如果你想修改地图的内容,删除 const 并保留 & (如果直接修改容器内部的内容)。如果你想使用容器值的副本,则也要删除 & 标记;然后,您可以通过在“变量名”上使用.first.second来访问它们。

1

其他方式:

map <int, string> myMap = {
    { 1,"Hello" },
    { 2,"stackOverflow" }
};
for (auto iter = cbegin(myMap); iter != cend(myMap); ++iter) {
    cout << iter->second << endl;
}

2
“仅有代码的答案并不是高质量的答案”(https://meta.stackoverflow.com/questions/392712/explaining-entirely-code-based-answers)。虽然这段代码可能很有用,但您可以通过解释它为什么有效、如何有效、何时应该使用以及其限制是什么来改进它。请编辑您的答案,包括解释和相关文档链接。 - Muhammad Mohsin Khan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接