能否通过C++模板将两个相似的成员函数合并为一个?
如何用模板合并重复的成员函数?
我定义了两个结构体:
S_BETHEL_SPEAKER_SERVICE_TALK_INFOS_MEMORIAL_INFO
目前实现了两个逻辑几乎完全一致的成员函数,代码如下:
void CMeetingScheduleAssistantApp::UpdateBethelServiceTalkInfo(COleDateTime datSpecialEvent, const S_BETHEL_SPEAKER_SERVICE_TALK_INFO sBSSTI) { const CString strDateKey = datSpecialEvent.Format(_T("%Y-%m-%d")); if (m_mapSpecialEvents.find(strDateKey) != m_mapSpecialEvents.end()) { S_SPECIAL_EVENT sEvent = m_mapSpecialEvents[strDateKey]; sEvent.sBSSTI = sBSSTI; m_mapSpecialEvents[strDateKey] = sEvent; // Update SaveEventsList(); } } void CMeetingScheduleAssistantApp::UpdateMemorialInfo(COleDateTime datSpecialEvent, const S_MEMORIAL_INFO sMI) { const CString strDateKey = datSpecialEvent.Format(_T("%Y-%m-%d")); if (m_mapSpecialEvents.find(strDateKey) != m_mapSpecialEvents.end()) { S_SPECIAL_EVENT sEvent = m_mapSpecialEvents[strDateKey]; sEvent.sMI = sMI; m_mapSpecialEvents[strDateKey] = sEvent; // Update SaveEventsList(); } }
请问是否可以通过模板将它们合并为一个函数?
当然可以用模板合并这两个函数,核心是把结构体类型和S_SPECIAL_EVENT对应的成员变量赋值逻辑抽象出来,以下是两种实用方案:
方案1:模板结合成员指针
通过模板指定要更新的结构体类型,同时传入S_SPECIAL_EVENT中对应成员的指针,统一完成赋值逻辑:
template<typename T> void UpdateSpecialEventInfo(COleDateTime datSpecialEvent, const T& info, T S_SPECIAL_EVENT::*memberPtr) { const CString strDateKey = datSpecialEvent.Format(_T("%Y-%m-%d")); auto it = m_mapSpecialEvents.find(strDateKey); if (it != m_mapSpecialEvents.end()) { S_SPECIAL_EVENT sEvent = it->second; sEvent.*memberPtr = info; m_mapSpecialEvents[strDateKey] = sEvent; SaveEventsList(); } }
调用时直接传入对应成员指针即可:
// 更新Bethel服务信息 UpdateSpecialEventInfo(dat, sBSSTI, &S_SPECIAL_EVENT::sBSSTI); // 更新纪念活动信息 UpdateSpecialEventInfo(dat, sMI, &S_SPECIAL_EVENT::sMI);
方案2:模板结合Lambda表达式
如果未来赋值逻辑需要额外处理,用Lambda封装赋值逻辑会更灵活:
template<typename T, typename AssignFunc> void UpdateSpecialEventInfo(COleDateTime datSpecialEvent, const T& info, AssignFunc assignFunc) { const CString strDateKey = datSpecialEvent.Format(_T("%Y-%m-%d")); auto it = m_mapSpecialEvents.find(strDateKey); if (it != m_mapSpecialEvents.end()) { S_SPECIAL_EVENT sEvent = it->second; assignFunc(sEvent, info); m_mapSpecialEvents[strDateKey] = sEvent; SaveEventsList(); } }
调用时传入Lambda完成赋值:
// 更新Bethel服务信息 UpdateSpecialEventInfo(dat, sBSSTI, [](S_SPECIAL_EVENT& event, const auto& info) { event.sBSSTI = info; }); // 更新纪念活动信息 UpdateSpecialEventInfo(dat, sMI, [](S_SPECIAL_EVENT& event, const auto& info) { event.sMI = info; });
额外优化说明
原代码中使用m_mapSpecialEvents[strDateKey]查找会触发键不存在时的默认构造,改用find()获取迭代器后直接操作it->second,能避免不必要的性能开销,上述方案已做此优化。
内容的提问来源于Stack Exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

