0

Code:

std::map<CString, S_DISCUSSION_HIST_ITEM> mapHistory;
// History list is in ascending date order
for (auto& sHistItem : m_listDiscussionItemHist)
{
    if (m_bFullHistoryMode)
        mapHistory.emplace(sHistItem.strName, sHistItem);
    else if (sHistItem.eSchool == m_eActiveSchool)
        mapHistory.emplace(sHistItem.strName, sHistItem);
}
// The map is sorted by Name (so reset by date later)
// The map has the latest assignment info for each Name now

Observation:

I now understand that std::emplace behaves like this:

The insertion only takes place if no other element in the container has a key equivalent to the one being emplaced (keys in a map container are unique).

Therefore my code is flawed. What I was hoping to acheive (in pseudo code) is:

For Each History Item
   Is the name in the map?
      No, so add to map with sHitItem
      Yes, so replace the sHistItem with this one
End Loop

By the end of this loop iteration I want to have the most recent sHitItem, for each person. But as it is, it is only adding an entry into the map if the name does not exist.

What is the simplest way to get around this?

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
  • 1
    I have just seen this answer which might resolve this: https://stackoverflow.com/a/51079331/2287576 – Andrew Truckle Oct 31 '21 at 19:23
  • 1
    pretty much whole `Is the name in the map?...` thing is just equivalent of `mapHistory[sHistItem.strName] = sHistItem;`. operator[] does what you want if your data object is assignable. – Swift - Friday Pie Oct 31 '21 at 19:40
  • @Swift-FridayPie Yes, as exaplained to me in an answer. I guess I was thinking that the `[]` operator behaved like in a normal array where it would break if it was not valid. Thanks for the clarification. – Andrew Truckle Oct 31 '21 at 19:43
  • 1
    there is `at()` method for that. The [] behavior might be unwanted in some cases because it always creates an element if it doesn't exist. Though instead of `at` it's better just to use `find`. Once upon a time there was some controversial articles about this in regard to STL (then-Morozov's library) design. – Swift - Friday Pie Oct 31 '21 at 20:12

1 Answers1

1

Use insert_or_assign method if the item is assignable. It will be assigned if it already exists. Or use [] operator followed by assignment, it will default-construct item if it does not exist.

For non-assignable types I'm afraid there's no convenient way.

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79