508

I want to iterate through each element in the map<string, int> without knowing any of its string-int values or keys.

What I have so far:

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?  
       }
}
2
  • 4
    Possible duplicate of How to loop through a c++ map Commented Apr 26, 2016 at 1:06
  • 3
    you most probably don't want the function to get the map by value, would be better to get it as const map<string, int>& table Commented Sep 20, 2020 at 19:59

8 Answers 8

1028

You can achieve this like following :

map<string, int>::iterator it;

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

With C++11 ( and onwards ),

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

With C++17 ( and onwards ),

for (auto const& [key, val] : table)
{
    std::cout << key        // string (key)
              << ':'  
              << val        // string's value
              << std::endl;
}
Sign up to request clarification or add additional context in comments.

21 Comments

add the "auto" type in front of "it"
@P0W Why "auto const&" for C++11 but "const auto&" for C++17? Any difference between "auto const&" and "const auto&"?
There is no difference, it's just a matter of taste. However it seems like @P0W 's taste is not very conistent...
Thanks for updating with the C++17 one, I was looking for the auto const& [key, val] : symbolTable format!
@haram You might have to set "ISO C++17 Standard (/std:c++17)" in the project settings (Configuration Properties > C/C++ > Language > C++ Language Standard)
|
39

Try the following

for ( const auto &p : table )
{
   std::cout << p.first << '\t' << p.second << std::endl;
} 

The same can be written using an ordinary for loop

for ( auto it = table.begin(); it != table.end(); ++it  )
{
   std::cout << it->first << '\t' << it->second << std::endl;
} 

Take into account that value_type for std::map is defined the following way

typedef pair<const Key, T> value_type

Thus in my example p is a const reference to the value_type where Key is std::string and T is int

Also it would be better if the function would be declared as

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

Comments

14

The value_type of a map is a pair containing the key and value as it's first and second member, respectively.

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

Or with C++11, using range-based for:

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

Comments

13

As @Vlad from Moscow says, Take into account that value_type for std::map is defined the following way:

typedef pair<const Key, T> value_type

This then means that if you wish to replace the keyword auto with a more explicit type specifier, then you could this;

for ( const pair<const string, int> &p : table ) {
   std::cout << p.first << '\t' << p.second << std::endl;
} 

Just for understanding what auto will translate to in this case.

Comments

12

As P0W has provided complete syntax for each C++ version, I would like to add couple of more points by looking at your code

  • Always take const & as argument as to avoid extra copies of the same object.
  • use unordered_map as its always faster to use. See this discussion

here is a sample code:

#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;
}

2 Comments

can you explain, how multiple copies of same object can get created if we don't use const& ? Is there any edge condition when it can happen?
@AshutoshTiwari its the reference of the variable & which avoids creating the multiple copies and when we take the reference, we do not want it to be modified hence we use const
6

if you just want to iterate over the content without changing values do:

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

If you want to modify the contents of the map, remove the const and keep & (if you want to modify directly the contents inside container). If you want to work with a copy of the container values, remove the & sign too; after that, you can access them by using .first and .second on "variable_name".

Comments

4

it can even be done with a classic for loop.
advancing the iterator manually.

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++;
}

Comments

2

Other way :

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

1 Comment

A code-only answer is not high quality. While this code may be useful, you can improve it by saying why it works, how it works, when it should be used, and what its limitations are. Please edit your answer to include explanation and link to relevant documentation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.