You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否通过C++模板将两个相似的成员函数合并为一个?

如何用模板合并重复的成员函数?

我定义了两个结构体:

  • S_BETHEL_SPEAKER_SERVICE_TALK_INFO
  • S_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 07:35:22