C++ 在一个方法中只构造一次std:map

C++ 在一个方法中只构造一次std:map,c++,mfc,stdmap,C++,Mfc,Stdmap,我有一个静态方法: CString COutlookCalendarSettingsDlg::GetExitCodeAsString(DWORD dwExitCode) { using OutlookExitCodesMap = std::map<DWORD, CString>; OutlookExitCodesMap mapExitCodes; mapExitCodes.insert(std::pair<DWORD, CString>(1,

我有一个静态方法:

CString COutlookCalendarSettingsDlg::GetExitCodeAsString(DWORD dwExitCode)
{
    using OutlookExitCodesMap = std::map<DWORD, CString>;

    OutlookExitCodesMap mapExitCodes;

    mapExitCodes.insert(std::pair<DWORD, CString>(1, _T("NoError")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-1, _T("CommandLineArguments")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-2, _T("BuildingCalendarList")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-3, _T("CalendarEventsPathNullEmpty")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-4, _T("CalendarEventsPathNotFound")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-5, _T("ModeSwitchNotSpecified")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-6, _T("ModeSwitchInvalid")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-7, _T("AddEventsMWB")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-8, _T("AddEventsSRR")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-9, _T("SignOut")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-10, _T("ReadMWBData")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-11, _T("ReadSRRData")));

    return mapExitCodes[dwExitCode];
}
CString COutlookCalendarSettingsDlg::getExitCodeString(DWORD dwExitCode) { 使用outlookExitCodeMap=std::map; OutlookExitCodes地图ExitCodes; 插入(std::pair(1,_T(“无错误”)); insert(std::pair(-1,_T(“CommandLineArguments”)); insert(std::pair(-2,_T(“BuildingCalendarList”); 插入(std::pair(-3,_T(“CalendarEventsPathNullEmpty”); 插入(std::pair(-4,_T(“CalendarEventsPathNotFound”); 插入(std::pair(-5,_T(“ModeSwitchNotSpecified”); 插入(std::pair(-6,_T(“ModeSwitchInvalid”); 插入(std::pair(-7,_T(“AddEventsMWB”); 插入(std::pair(-8,_T(“addeventsrr”)); 插入(std::pair(-9,_T(“注销”)); 插入(std::pair(-10,_T(“ReadMWBData”); 插入(std::pair(-11,_T(“ReadSRRData”)); 返回mapExitCodes[dwExitCode]; } 现在,我知道我可以将其转换为类中的全局变量,然后让
getExitCodeString
方法从该全局变量返回

但是,如何在方法中定义映射,而只构建一次?我不需要继续重建它。因此,第一次调用它时,它将构造它,随后它将只返回值


这能做到吗?

答案很简单,但很难看:

CString COutlookCalendarSettingsDlg::GetExitCodeAsString(DWORD dwExitCode)
{
  using OutlookExitCodesMap = std::map<DWORD, CString>;

  static OutlookExitCodesMap mapExitCodes;

  if (mapExitCodes.size()==0)
  {
    mapExitCodes.insert(std::pair<DWORD, CString>(1, _T("NoError")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-1, _T("CommandLineArguments")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-2, _T("BuildingCalendarList")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-3, _T("CalendarEventsPathNullEmpty")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-4, _T("CalendarEventsPathNotFound")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-5, _T("ModeSwitchNotSpecified")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-6, _T("ModeSwitchInvalid")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-7, _T("AddEventsMWB")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-8, _T("AddEventsSRR")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-9, _T("SignOut")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-10, _T("ReadMWBData")));
    mapExitCodes.insert(std::pair<DWORD, CString>(-11, _T("ReadSRRData")));
  }
  return mapExitCodes[dwExitCode];
}
CString COutlookCalendarSettingsDlg::getExitCodeString(DWORD dwExitCode) { 使用outlookExitCodeMap=std::map; 静态了望EXITCODESMAP EXITCODES; 如果(mapExitCodes.size()==0) { 插入(std::pair(1,_T(“无错误”)); insert(std::pair(-1,_T(“CommandLineArguments”)); insert(std::pair(-2,_T(“BuildingCalendarList”); 插入(std::pair(-3,_T(“CalendarEventsPathNullEmpty”); 插入(std::pair(-4,_T(“CalendarEventsPathNotFound”); 插入(std::pair(-5,_T(“ModeSwitchNotSpecified”); 插入(std::pair(-6,_T(“ModeSwitchInvalid”); 插入(std::pair(-7,_T(“AddEventsMWB”); 插入(std::pair(-8,_T(“addeventsrr”)); 插入(std::pair(-9,_T(“注销”)); 插入(std::pair(-10,_T(“ReadMWBData”); 插入(std::pair(-11,_T(“ReadSRRData”)); } 返回mapExitCodes[dwExitCode]; } 此代码对于多线程不安全。此外,如果存在未知的exitcode,则映射将增长。不需要这个

但是为什么要使用一个映射来实现这样简单的代码呢。更简单,不使用任何堆,甚至不使用任何构造:

CString COutlookCalendarSettingsDlg::GetExitCodeAsString(DWORD dwExitCode)
{
  using OutlookExitCodesMap = std::map<DWORD, CString>;


  static const struct { 
    int     dwCode;
    LPCTSTR pszText;
  } 
  aMap[] = 
  {
    1, _T("NoError"),
    -1, _T("CommandLineArguments"),
    -2, _T("BuildingCalendarList"),
    -3, _T("CalendarEventsPathNullEmpty"),
    -4, _T("CalendarEventsPathNotFound"),
    -5, _T("ModeSwitchNotSpecified"),
    -6, _T("ModeSwitchInvalid"),
    -7, _T("AddEventsMWB"),
    -8, _T("AddEventsSRR"),
    -9, _T("SignOut"),
    -10, _T("ReadMWBData"),
    -11, _T("ReadSRRData"),
  };
  for (const auto &data : aMap)
  {
    if (static_cast<DWORD>(data.dwCode)==dwExitCode)
       return data.pszText;
  }

  return CString();
}
CString COutlookCalendarSettingsDlg::getExitCodeString(DWORD dwExitCode) { 使用outlookExitCodeMap=std::map; 静态常量结构{ int-dwCode; LPCTSTR-pszText; } aMap[]= { 1、_T(“无错误”), -1、_T(“命令行参数”), -2、_T(“构建日历列表”), -3、_T(“CalendarEventsPathNullEmpty”), -4、_T(“CalendarEventsPathNotFound”), -5、_T(“未指定模式开关”), -6、_T(“模式切换无效”), -7,_T(“附录MWB”), -8,_T(“附录”), -9、_T(“签出”), -10,_T(“ReadMWBData”), -11、_T(“读取数据”), }; 用于(常数自动和数据:aMap) { if(静态_转换(data.dwCode)==dwExitCode) 返回data.pszText; } 返回CString(); }
代码可能有输入错误。。。我只是从头开始写的

这是另一个基于对我的问题的评论的解决方案:

CString COutlookCalendarSettingsDlg::GetExitCodeAsString(DWORD dwExitCode)
{
    switch (dwExitCode)
    {
    case 1: return _T("NoError");
    case -1: return _T("CommandLineArguments");
    case -2: return _T("BuildingCalendarList");
    case -3: return _T("CalendarEventsPathNullEmpty");
    case -4: return _T("CalendarEventsPathNotFound");
    case -5: return _T("ModeSwitchNotSpecified");
    case -6: return _T("ModeSwitchInvalid");
    case -7: return _T("AddEventsMWB");
    case -8: return _T("AddEventsSRR");
    case -9: return _T("SignOut");
    case -10: return _T("ReadMWBData");
    case -11: return _T("ReadSRRData");
    }

return CString();

}

谢谢你的帮助。我将
for
循环简化为
for(auto&I:aMap)
。我将返回值改为
\u T(“”
)。我没有看到其他错误。因此使用关键字的
现在已经过时了。我试图给
struct
命名
OutlookExitCode
,但是
aMap
抱怨缺少
。是的,使用新的for语法更容易。如果使用一个名称作为结构,你必须将声明和定义分开。啊,那么你提供的是一种特殊的编码风格。别担心。我以前从未这样做过。谢谢。我确实收到一个编译警告:警告C4838:从“int”到“DWORD”的转换需要缩小转换范围。这是数值常量。负数永远不是双字。将0xFFFFFF用于-1。或者在结构中使用int,在比较中使用cast。更改了我的答案。我将在这里使用一个简单的
开关(dwExitCode)
,它将与您的map解决方案同等甚至更有效。由于大多数大小写值都是连续的,编译器可以构建一个有效的跳转表。@zett42所以您认为是一个
开关
语句,每个语句都有一个
返回(“xxxxx”)节点将是最佳解决方案?@zett42与答案中使用
struct
的其他建议相比如何?我现在正在使用它。switch语句,每个语句都有一个返回_T(“xxxxx”);-这就是我的想法。使用struct的建议仍然比
switch
语句更复杂,因此我更喜欢
switch
@zett42我接受了最初的答案,但作为第二个答案,我提供了您的想法。是的,我认为这是最干净的代码,不会比其他解决方案效率低,原因我已经在问题注释中写过了。