5

I'm trying to understand the "theory" besides the auto loop over

std::map

elements in C++. I have a std::map with a std::string as KEY and a vector<std:string> as VALUE. I can access its elements with:

for ( auto &element : myMap ) {
    std::cout << element.first << ": " << '\t';
    for ( std::string subElement : element.second ) std::cout << subElement << ", ";
  }
}

as for the loop over the vector<string> elements I know that I could put "auto" instead of "std::string". But what would be the equivalent for the map in such case? I studied and searched around and I found in that post that each map element is accessed as a

map< K, V>::value_type

but how would I write it down? I tried:

for ( std::map<std::string, vector<std::string>> &pz : myMap ) {
    // print ...
}

and similars, but they just does not work.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
cccnrc
  • 1,195
  • 11
  • 27

2 Answers2

8

std::map::value_type is defined as the type of std::map's element, which is std::pair<const Key, T> (i.e. std::pair<const std::string, vector<std::string>> here). You should use it as

for ( std::map<std::string, vector<std::string>>::value_type &pz : myMap ) {
    //                                          ^^^^^^^^^^^^
    // print ...
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • it was that intuitive...so indicatively "::value_type" make C++ interpret it as a "single element" of which access the subelements? – cccnrc Jun 17 '19 at 03:21
  • 1
    @cccnrc Yes, and the element of `std::map` is `std::pair` indeed. – songyuanyao Jun 17 '19 at 03:24
  • 1
    @cccnrc `std::map` is a map. `std::map::value_type` is a member type of the `std::map` class, and as its name suggests, it is the type of a value in the map. – eesiraed Jun 17 '19 at 04:45
  • 2
    @cccnrc It's a bit confusing since a map contains _key-value_ pairs, but `value_type` is not a type of stored _values_, but a type of whole entries (key-value pairs). The type of values is spelled as `mapped_type`. – Daniel Langr Jun 17 '19 at 06:22
  • Perhaps use `reference` instead of `value_type &` though… – Arne Vogel Jun 18 '19 at 08:30
  • don't we need `typename` as `value_type` is dependent to the `std::pair`? – UserUsing Jun 18 '19 at 10:10
  • 1
    @UsingCpp For `std::map>`, `typename` is not required; all the template arguments have been determined. – songyuanyao Jun 18 '19 at 10:12
0

songyuanyao has answered your question. One thing needed to be clarified here is that std::map is defined as

template<
    class Key,
    class T,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T> >
> class map;

The class name should be std::map<key type, value type>.

khanh
  • 600
  • 5
  • 20