0

I have decided to revisit this question (Is it possble to return a reference to a std::map?) because it is not correct for me.

My application class has these methods to retreive a map:

SpecialEventDataMap& GetEventsListMap() noexcept
{
    return m_mapSpecialEvents;
}

const SpecialEventDataMap& GetEventsListMap() const noexcept
{
    return m_mapSpecialEvents;
}

The variable m_mapSpecialEvents is defined:

using SpecialEventDataMap = std::map<CString, SPECIAL_EVENT_S>;

My main app build a map of special events. This is retreived in my month / calendar control class:

CMyMonthCalCtrl::CMyMonthCalCtrl() noexcept(false)
: m_pReminders(nullptr)
{
    m_mapSpecialEvents = theApp.GetEventsListMap();
}

In my application dialog, which has the calendar control, we display a popup dialog where the user can add events. When that dialog returns, we save the content to disk:

theApp.SaveEventsList();

In the end I had to get the main application class to update it's own map:

theApp.AddOrUpdateEventInList(sEvent);

Why did I have to do this? I have since noticed that I also have to call a new function in the calendar class to:

m_calStart.RefreshMap();
m_calEnd.RefreshMap();

Why did my original attempt to get a reference to the map in the app class not work? It clearly made a copy/ I know this because my calendar displays a tooltip for all special events. And unless I restarted the app the tips did not show. When I refreshed the map so that it was the latest instance it worked.

I understood that this code shoudl return a reference. And that I shoudl be able to add / remove from it inside the class that retreieved it, and that the main app class where the original is should be in sync. But not.

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
  • 1
    `theApp.GetEventsListMap()` returns a reference all right. But what you then do with that reference is pass it to `std::map::operator=(const std::map& other)`, which makes a copy of `other`. If you want to actually store the reference to the original map, then `CMyMonthCalCtrl::m_mapSpecialEvents` should be declared as a `map&`, not as `map` (then you'd have to initialize it in constructor initializer list). – Igor Tandetnik Jan 18 '22 at 14:45
  • 1
    Consider: `int x = 1; int y = x; x = 2;` Here `y` is still 1 - would you have expected differently? That's what your current code is doing. You seem to want `int& y = x;` instead - now `x` and `y` refer to the same object, and so changes through one are visible through the other. – Igor Tandetnik Jan 18 '22 at 14:47
  • @IgorTandetnik What you say is making sense to me. So my `CMyMonthCalCtrl` member variable needs to be declared as `SpecialEventDataMap& m_mapSpecialEvents;`. And then in the initializer list: `m_mapSpecialEvents(theApp.theApp.GetEventsListMap())` and remove it from the internal braces of the constructor? – Andrew Truckle Jan 18 '22 at 14:57
  • 1
    Yes, this should work (except that you don't repeat `theApp.theApp.` twice) – Igor Tandetnik Jan 18 '22 at 15:02
  • @IgorTandetnik That was typo. Let me test ... – Andrew Truckle Jan 18 '22 at 15:04
  • @IgorTandetnik That worked! The penny had dropped into place in my mind now. Thank you. – Andrew Truckle Jan 18 '22 at 15:09

0 Answers0