在方法中仅构造一次 std:map
Constructing a std:map only once within a method
我有这个静态方法:
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];
}
现在,我知道我可以将它变成 class 中的全局变量,然后从这个全局变量中获取 GetExitCodeAsString
方法 return。
但是我怎样才能在方法中定义地图,但是,只构造一次呢?我不需要继续重建它。因此,第一次调用它时会构造它,随后的时间它只会 return 值。
这可以做到吗?
答案简单但丑陋:
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::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::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();
}
我有这个静态方法:
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];
}
现在,我知道我可以将它变成 class 中的全局变量,然后从这个全局变量中获取 GetExitCodeAsString
方法 return。
但是我怎样才能在方法中定义地图,但是,只构造一次呢?我不需要继续重建它。因此,第一次调用它时会构造它,随后的时间它只会 return 值。
这可以做到吗?
答案简单但丑陋:
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::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::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();
}