Reputation: 467
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
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
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
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