Can I access the elements in a c++ std::map by an integer index?

Charles picture Charles · Aug 2, 2011 · Viewed 23.1k times · Source

I have a map of elements that I would like to iterate through. Of course, the standard way to do that would be using a for loop with

for (map<string, int> iterator it = myMap.begin(); it != myMap.end(); ++it) {
    string thisKey = it->first;
    int thisValue = it->second;
}

but if I try and make this loop run parallel using OpenMP's parallel for construct, it doesn't work, and this is (apparently) a known issue, as it doesn't recognize this sort of loop construct.

So, my backup plan was to use an integer index iterator, and access the list of keys and values by index, as I would do in C# like so:

for (int i = 0; i < myMap.Count; ++i) {
    string thisKey = myMap.Keys[i];
    string thisValue = myMap.Values[i];
}

... yet I can't seem to find an equivalent method in C++. Is there a way to do this in C++ that I'm unaware of?

Answer

Robᵩ picture Robᵩ · Aug 3, 2011

I don't know anything about OpenMP, so I don't know if it will optimize the following or not. But you could use std::advance, like so:

#include <map>
#include <string>
#include <iterator>
#include <iostream>

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

int main() {
  Map m;
  m["one"] = 1;
  m["two"] = 2;
  for(int i = 0; i < m.size(); ++i) {
    Map::iterator it = m.begin();
    std::advance(it, i);
    std::string thiskey = it->first;
    int thisValue = it->second;
    std::cout << thiskey << "\n";
  }
}

But do be aware that std::advance is O(n), so your (single-threaded) complexity is O(n^2).


EDIT: If you copy the map elements to a vector, realize you can do that in one declaration:

std::vector<Map::value_type> v(m.begin(), m.end());

thus:

#include <map>
#include <string>
#include <iterator>
#include <iostream>
#include <vector>

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

int main() {
  Map m;
  m["one"] = 1;
  m["two"] = 2;
  int i = 0;
  for( std::vector<Map::value_type> v(m.begin(), m.end());
    i < v.size(); ++i) {
    std::string thiskey = v[i].first;
    int thisValue = v[i].second;
    std::cout << thiskey << "\n";
  }
}