std::map使用std::emplace无法覆盖已有键,如何保留每个键的最新值?
最简单实现方案
你只需要把原有代码里的emplace调用替换为std::map的operator[]赋值即可,这是C++11及以上标准下最简洁的写法,完全匹配你需要的「不存在则插入、存在则更新」逻辑:
std::map<CString, S_DISCUSSION_HIST_ITEM> mapHistory; // History list is in ascending date order for (auto& sHistItem : m_listDiscussionItemHist) { if (m_bFullHistoryMode || sHistItem.eSchool == m_eActiveSchool) { // 键不存在时自动插入,存在时直接覆盖原有值 mapHistory[sHistItem.strName] = sHistItem; } }
补充方案
1. C++17及以上标准优化方案
如果你的项目使用C++17或更高版本标准,可以用insert_or_assign方法,语义更明确,且不需要S_DISCUSSION_HIST_ITEM类型支持默认构造,执行效率也优于operator[]:
// 替换上述赋值行为即可 mapHistory.insert_or_assign(sHistItem.strName, sHistItem);
2. C++11无默认构造兼容方案
如果你的项目使用C++11标准,且S_DISCUSSION_HIST_ITEM不支持默认构造,也可以手动判断后操作:
auto it = mapHistory.find(sHistItem.strName); if (it == mapHistory.end()) { mapHistory.emplace(sHistItem.strName, sHistItem); } else { it->second = sHistItem; }
原理解释
你的历史列表本身是按日期升序排列的,遍历过程中后出现的同姓名条目就是更新的记录,上述几种方案都会用新条目覆盖旧条目,最终map里存储的就是每个姓名对应的最新历史记录。
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

