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 map
s 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 getsinserted
intomyMap
.- Somehow, I don't know how it happens, the
temporary copy of a
gets destructed immediately. To me, it means the memory of thetemporary copy of a
is 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 a
get 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 tillmain
finishes.Is my boss's code incorrect and very dangerous?