I’m trying to get const pointers to each value in std::map. I tried const pair<...>& with its .second attribute but got wrong pointers. However, the const_ierator goes right.
A piece of simple toy code:
const map<int, double> intMap = {{1, 3.3}, {4, 5.7}, {2, 8.314}};
const double* cPtr;
for (const pair<int, double>& cPair: intMap)
{
cPtr = &(cPair.second);
cout << cPtr << endl;
}
cout << endl;
for (
map<int, double>::const_iterator mapIter = intMap.begin();
mapIter != intMap.end();
mapIter ++
)
cout << &(mapIter -> second) << endl;
Which returns:
0x7ffc553c8210 # wrong pointers
0x7ffc553c8210
0x7ffc553c8210
0xb3ced8 # which I want
0xb3cf58
0xb3cf18
My questions:
- Why can’t I (or How can I) force the
.secondofconst pair<>&to return a reference rather than a copy? - If I cannot get what I want with
const pair<>&, is there any more convenient way to get value references rather than usingconst_iterator, which seems really stupid?
>Solution :
Why can’t I (or How can I) force the
.secondofconst pair<>&to return a reference rather than a copy?
Copy doesn’t happen with .second, but with mismatching type for std::pair.
Deferencing a map (const) iterator returns a /*const*/std::pair<const Key, Value>& (note the extra const).
When you do
for (const pair<int, double>& cPair: intMap)
You have a temporary pair<int, double> created from pair<const int, double> (that is why you see the same address).
If I cannot get what I want with
const pair<>&, is there any more convenient way to get value references rather than using const_iterator, which seems really stupid?
You can with proper type:
for (const std::pair<const int, double>& cPair : intMap)
or with auto being less explicit but avoid any typo:
for (const auto& cPair : intMap)
or in C++17, with struture binding
for (const auto& [i, d] : intMap)