user3798283
user3798283

Reputation: 467

map inside map in C++ . Pretty confusing?

I am little confused here one map which has name myMap is a map inside map obviously on value side while the second map is a very normal map of int vs char . No in one case (which is myMap) it is allowing duplicate keys (abnormal behaviour) while in another case it doesn't .

#include <iostream>
#include <map> 
using namespace std;
int main(void)
{ 
    map<int, map<int,char> > myMap;   // map inside map
    map<int, char> ourMap;            // normal map

    myMap[1][1] = 'A';
    myMap[1][2] = 'B';     // should overwrite  previous value
    myMap[2][1] = 'C';
    myMap[2][2] = 'D';     // should overwrite  previous value

    ourMap[1] = 'A';
    ourMap[1] = 'B';

    cout << "[1][1] = " << myMap[1][1] << endl;
    cout << "[1][2] = " << myMap[1][2] << endl;
    cout << "[2][1] = " << myMap[2][1] << endl;
    cout << "[2][2] = " << myMap[2][2] << endl;

    cout << "ourMap[1] = " << ourMap[1] << endl;

    return 0;
}
// And here is the output . By the way I was anticipating , [1][2] = B , [2][2] = D & ourMap[1] = B . But something else comes out . 

OUTPUT :

[1][1] = A
[1][2] = B
[2][1] = C
[2][2] = D
ourMap[1] = B

Is if we have map inside map does in C++ they start deviating from their normal behavior which is can't have duplicate keys I am not able to figure it out how it is so . Can anyone tell me how it is so ? Extremely sorry if the question sounds funny ?

My Question is for myMap 
myMap[x][y] = something
u can have only distinct value of x ?
For normal map it is like that only . 

Upvotes: 0

Views: 1595

Answers (3)

user7611475
user7611475

Reputation: 76

The [] operator does a find and insert if not found. It returns an iterator to a value given a key.

Thus doing myMap[1] returns an iterator to a map<int,char>.

Then doing myMap[1][1] returns an iterator to a char as the second [] is being called on the iterator returned from myMap[1].

So doing myMap[1][1] = 'A' and myMap[1][2] = 'B' is no different than ourMap[1] = 'A' and ourMap[2] = 'B'.

Upvotes: 0

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385405

You're imagining a problem where none exists.

There are no "duplicate keys".

Your container could be visualised thus:

"myMap"                              map<int, map<int,char>>
  |
  +-- [1]  "myMap[1]"                map<int,char>
  |          |
  |          +-- [1]  "myMap[1][1]"  char
  |          |
  |          +-- [2]  "myMap[1][2]"  char
  |
  +-- [2]  "myMap[2]"                map<int,char>
             |
             +-- [1]  "myMap[2][1]"  char
             |
             +-- [2]  "myMap[2][2]"  char

On this line:

myMap[1][1] = 'A';

you access (and, since it doesn't exist yet, create) myMap[1].

Then, with myMap[1], you access key 1 of the inner map and assign 'A'.

Next, on this line:

myMap[1][2] = 'B';

you again access myMap[1]. Nothing needs to be "overwritten"; you're just accessing the first element in myMap[1] again.

This time, you access key 2 of the inner map and assign 'B'.


Here's another way of writing your code, using references to get a clearer name for those inner maps:

map<int,char>& firstInnerMap = myMap[1];
firstInnerMap[1] = 'A';
firstInnerMap[2] = 'B';

map<int,char>& secondInnerMap = myMap[2];
secondInnerMap[1] = 'C';
secondInnerMap[2] = 'D';

Alternatively, consider a map<int, string>:

map<int, string> myMap;
myMap[1] = "Hello";
myMap[1][0] = 'J';   // change string to "Jello"

We've accessed the string "called" myMap[1] and performed an operation on it (theString[0] = 'J'). This has no effect on myMap. No "overwriting" needs to occur.

When you're nesting a map instead, it's no different.

Upvotes: 3

user2100815
user2100815

Reputation:

OK:

   myMap[1][1] = 'A';   

when these functions are first called, myMap is empty. So,

   myMap[1]     // XXXX

creates an entry in that map with index 1. The thing created is itself a map. Then:

   myMap[1][1] = 'A';

creates an entry within the second, contained, map, and assigns 'A' to it.

Then

     myMap[1][2] = 'B';

looks up the map entry created at XXX with index 1 (which is itself a map) and adds an entry with key 2 and value B to that second, contained map.

So we have one entry in the top-level map, and two entries in the second level one.

Upvotes: 1

Related Questions