I don't understand why assigning to an iterator->second in a std::map modifies the value into the map
#include <typeinfo>
#include <map>
#include <iostream>
int main() {
std::map<int, int> lol;
lol[2] = 33;
auto it = lol.find(2);
it->second = 91; // This changes the map's value
std::cout << typeid(it->second).name(); // This just shows 'int', not a reference
std::cout << lol[2]; // 91
return 0;
}
isn't it->second
just an int and not a reference?
isn't
it->second
just an int and not a reference?
Yes, it is just an int
. *it
gives you a std::pair<int const, int>&
, a reference to the actual value of the node in the map
. But the member access to second
is in fact just an int
. The trait "is a reference" and the trait "is assignable to" are not equivalent - you can assign to non-references, and there are references you can't assign to. it->second
gives you an lvalue of type int
, that you can assign through, in the same way that:
int i = 4;
i = 5; // i is not a reference, but you can assign it here
That said, typeid()
wouldn't give you a reference type anyway because reference and cv-qualifications are dropped from type analysis. See also my answer here.
That said, what you probably want to look at is decltype((it->second))
(yes, double the parentheses, double the fun). This, in fact, gives you int&
, because that expression is an lvalue of type int
.