Today I saw my boss's code which uses a const reference as a map's value type.
Here's the code:
class ConfigManager{
public:
map<PB::Point, const PB::WorldPoint&, compare_point> world_point;
//the rest are omitted
};
(PB is Google Protobuf, we are using the Protobuf library. I don't know much about it or if it's relevant to the question. )
What this class does is that it reads some config files and put it into some maps for searhing.
At first I was surprised because I haven't seen a map with a reference as its value, which is e.g. map<int, classA&> aMap.
So then I searched on SO and these 2 questions tell me that I can't do that.
C++: Is it possible to use a reference as the value in a map?
STL map containing references does not compile
Then I tried this code, indeed it doesn't compile:
Code Example1
struct A {
int x = 3;
int y = 4;
};
map<int, A&> myMap;
int main() {
A a;
myMap.insert(make_pair(1, a));
}
But if I change map<int, A&> myMap; to map<int, const A&> myMap;, it compiles.
Yet another problem occured. With map<int, const A&> myMap;, I can't use [] to get the pair, but I can use map.find().
(My boss told me to use map.find() after I told him using[] can't compile).
Code Example2
struct A {
int x = 3;
int y = 4;
};
map<int, const A&> myMap;
int main() {
A a;
myMap.insert(make_pair(1, a));
//can't compile
cout << myMap[1].x << " " << myMap[1].y << endl;
//can work
//auto it = myMap.find(1);
//cout << it->second.x << " " << it->second.y << endl;
}
So till here I was thinking my boss was correct. His code was correct.
The last story is that I showed the code to some online friends. And they noticed a problem.
Code Example3
#include <map>
#include <iostream>
#include <string>
using namespace std;
struct A {
int x = 3;
int y = 4;
~A(){
cout << "~A():" << x << endl;
x = 0;
y = 0;
}
};
map<string, const A&> myMap;
int main() {
A a;
cout << a.x << " " << a.y << endl;
myMap.insert(make_pair("love", a));
a.x = 999;
cout << "hello" << endl;
auto s = myMap.find("love");
cout << s->second.x << " " << s->second.y << endl;
}
The output is:
3 4
~A():3
hello
0 0
~A():999
If I understand the output correctly(correct me if I get it wrong), it indicates that:
make_pair("love", a)creates an objectpair<"love", temproray copy of a>. And the pair getsinsertedintomyMap.- Somehow, I don't know how it happens, the
temporary copy of agets destructed immediately. To me, it means the memory of thetemporary copy of ais now not owned by anyone and it is now a free space of memory that can be filled with any values, if I understand correctly.
So now I am getting confused again.
My questions are:
What happens to the Code Example3? Is my understanding correct? Why does
temporary copy of aget destructed right after the statement? Isn't using a const reference can extend a temporary's lifetime? I mean, I think the it should not get destructed tillmainfinishes.Is my boss's code incorrect and very dangerous?