In the following code I am trying to edit the contents of an unordered_map:
class A {
public:
A() {std::cout << "Constructor called, address=" << this << std::endl;val=1;}
int val;
};
void main(void) {
std::unordered_map<int,A> um;
for (int i=0;i<3;i++)
std::cout << "um[" << i << "]=" << &(um[i]) << ", val=" << um[i].val << std::endl;
for (auto it : um)
std::cout << "&it.second=" << &(it.second) << ", val=" << it.second.val << std::endl;
int index = 1;
for (auto um_it : um)
um_it.second.val = index++;
for (int i=0;i<3;i++)
std::cout << "um[" << i << "]=" << &(um[i]) << ", val=" << um[i].val << std::endl;
for (auto it : um)
std::cout << "&it.second=" << &(it.second) << ", val=" << it.second.val << std::endl;
}
The output of the above is:
Constructor called, address=0x8dcb2c
um[0]=0x8dcb2c, val=1
Constructor called, address=0x8dc7ac
um[1]=0x8dc7ac, val=1
Constructor called, address=0x8dc42c
um[2]=0x8dc42c, val=1
&it.second=0x7ffc62f24484, val=1
&it.second=0x7ffc62f24484, val=1
&it.second=0x7ffc62f24484, val=1
um[0]=0x8dcb2c, val=1
um[1]=0x8dc7ac, val=1
um[2]=0x8dc42c, val=1
&it.second=0x7ffc62f24484, val=1
&it.second=0x7ffc62f24484, val=1
&it.second=0x7ffc62f24484, val=1
When I replace the editing code with:
int index = 1;
for (auto um_it = um.begin(); um_it != um.end(); ++um_it)
um_it->second.val = index++;
The output is:
Constructor called, address=0x9d8b2c
um[0]=0x9d8b2c, val=1
Constructor called, address=0x9d87ac
um[1]=0x9d87ac, val=1
Constructor called, address=0x9d842c
um[2]=0x9d842c, val=1
&it.second=0x7fffd2201c34, val=1
&it.second=0x7fffd2201c34, val=1
&it.second=0x7fffd2201c34, val=1
um[0]=0x9d8b2c, val=3
um[1]=0x9d87ac, val=2
um[2]=0x9d842c, val=1
&it.second=0x7fffd2201c34, val=1
&it.second=0x7fffd2201c34, val=2
&it.second=0x7fffd2201c34, val=3
I understand from the results that in the first version the code affects a copy of the objects, but it seems strange. I also expected the copy constructor to be called but it was not. I'd be happy if someone can explain what is going on behind the scenes and what would be the best way to iterate through an unordered_map without making redundant copies.
See Question&Answers more detail:
os