Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why does the .second reference of const std::pair& return a copy of second value rather than a const reference?

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

0x7ffc553c8210 # wrong pointers
0x7ffc553c8210
0x7ffc553c8210

0xb3ced8 # which I want
0xb3cf58
0xb3cf18

My questions:

  • Why can’t I (or How can I) force the .second of const 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 using const_iterator, which seems really stupid?

>Solution :

Why can’t I (or How can I) force the .second of const 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)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading