CMapStringToString 与 std::map<CString, CString>
CMapStringToString vs std::map<CString, CString>
在我的应用程序中迁移对 CMapStringToString
over to std::map<CString, CString>
的使用对我有什么真正的好处吗?
我不明白,我尝试更改代码,现在无法编译:
7>------ Build started: Project: Meeting Schedule Assistant, Configuration: Release x64 ------
7>CalendarSettingsOutlookPage.cpp
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\xhash(112,53): error C2064: term does not evaluate to a function taking 1 arguments
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\xhash(135): message : see reference to variable template 'const bool _Nothrow_hash<std::hash<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > >,ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > >' being compiled
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\xhash(135): message : while compiling class template member function 'size_t std::_Uhash_compare<_Kty,_Hasher,_Keyeq>::operator ()<_Kty>(const _Keyty &) noexcept(<expr>) const'
7> with
7> [
7> _Kty=CString,
7> _Hasher=std::hash<CString>,
7> _Keyeq=std::equal_to<CString>,
7> _Keyty=ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>
7> ]
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\xhash(1109): message : see reference to variable template 'const bool _Nothrow_hash<std::_Umap_traits<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,std::_Uhash_compare<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,std::hash<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > >,std::equal_to<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > > >,std::allocator<std::pair<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > const ,ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > > >,0>,ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > >' being compiled
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\xhash(1096): message : while compiling class template member function 'void std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>::clear(void) noexcept'
7> with
7> [
7> _Kty=CString,
7> _Ty=CString,
7> _Hasher=std::hash<CString>,
7> _Keyeq=std::equal_to<CString>,
7> _Alloc=std::allocator<std::pair<const CString,CString>>
7> ]
7>D:\My Programs22\MeetSchedAssist\Meeting Schedule Assistant\CalendarSettingsOutlookPage.cpp(156): message : see reference to function template instantiation 'void std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>::clear(void) noexcept' being compiled
7> with
7> [
7> _Kty=CString,
7> _Ty=CString,
7> _Hasher=std::hash<CString>,
7> _Keyeq=std::equal_to<CString>,
7> _Alloc=std::allocator<std::pair<const CString,CString>>
7> ]
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\unordered_map(67): message : see reference to class template instantiation 'std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>' being compiled
7> with
7> [
7> _Kty=CString,
7> _Ty=CString,
7> _Hasher=std::hash<CString>,
7> _Keyeq=std::equal_to<CString>,
7> _Alloc=std::allocator<std::pair<const CString,CString>>
7> ]
7>D:\My Programs22\MeetSchedAssist\Meeting Schedule Assistant\CalendarSettingsOutlookPage.h(59): message : see reference to class template instantiation 'std::unordered_map<CString,CString,std::hash<CString>,std::equal_to<CString>,std::allocator<std::pair<const CString,CString>>>' being compiled
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\xhash(111,44): error C2056: illegal expression
7>Done building project "Meeting Schedule Assistant.vcxproj" -- FAILED.
如果我使用 std::map<CString, CString>
它可以工作,但 std::unordered_map<CString, CString>
会抛出上述错误。我的用法调用:
if (m_mapCalendarList.find(strCalendarName) != m_mapCalendarList.end())
if (strCalendarId == m_mapCalendarList[strCalendarName])
m_mapCalendarList.clear();
变量定义在header.
MFC 哈希映射有一些缺点,除了不是 C++ 标准而且不是 portable:
- 不要自动重新计算哈希 table。 填充时甚至无法调整散列大小 table。散列的默认大小 table 可能不适合您。
- 如评论中所述,它们不支持基于范围的 for 或范围算法
- 不可复制,不可自行移动。移动容器可能会有用
- 不支持元素插入的移动语义,这涉及一些开销
对于std::unordered_map
,需要实现hash函数,作为对应的模板参数传入。或者为 CString
专门化标准哈希。但我更喜欢前者。
最好也传递比较函数,执行与语言环境无关的比较。由于使用不了解语言环境的散列,无论如何您都无法拥有语言环境感知地图,但是 CString::operator==
是语言环境感知的。
由于 HashKey
可以使用 LPCSTR
和 LPCWSTR
CMap
,实现自己的 STL 兼容散列是微不足道的。
你可以完全避免处理哈希,而使用std::unordered_map<std::string, std::string>
。但过渡到 std::string
会导致更多变化,我猜。
在我的应用程序中迁移对 CMapStringToString
over to std::map<CString, CString>
的使用对我有什么真正的好处吗?
我不明白,我尝试更改代码,现在无法编译:
7>------ Build started: Project: Meeting Schedule Assistant, Configuration: Release x64 ------
7>CalendarSettingsOutlookPage.cpp
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\xhash(112,53): error C2064: term does not evaluate to a function taking 1 arguments
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\xhash(135): message : see reference to variable template 'const bool _Nothrow_hash<std::hash<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > >,ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > >' being compiled
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\xhash(135): message : while compiling class template member function 'size_t std::_Uhash_compare<_Kty,_Hasher,_Keyeq>::operator ()<_Kty>(const _Keyty &) noexcept(<expr>) const'
7> with
7> [
7> _Kty=CString,
7> _Hasher=std::hash<CString>,
7> _Keyeq=std::equal_to<CString>,
7> _Keyty=ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>
7> ]
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\xhash(1109): message : see reference to variable template 'const bool _Nothrow_hash<std::_Umap_traits<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,std::_Uhash_compare<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,std::hash<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > >,std::equal_to<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > > >,std::allocator<std::pair<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > const ,ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > > >,0>,ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > >' being compiled
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\xhash(1096): message : while compiling class template member function 'void std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>::clear(void) noexcept'
7> with
7> [
7> _Kty=CString,
7> _Ty=CString,
7> _Hasher=std::hash<CString>,
7> _Keyeq=std::equal_to<CString>,
7> _Alloc=std::allocator<std::pair<const CString,CString>>
7> ]
7>D:\My Programs22\MeetSchedAssist\Meeting Schedule Assistant\CalendarSettingsOutlookPage.cpp(156): message : see reference to function template instantiation 'void std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>::clear(void) noexcept' being compiled
7> with
7> [
7> _Kty=CString,
7> _Ty=CString,
7> _Hasher=std::hash<CString>,
7> _Keyeq=std::equal_to<CString>,
7> _Alloc=std::allocator<std::pair<const CString,CString>>
7> ]
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\unordered_map(67): message : see reference to class template instantiation 'std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>' being compiled
7> with
7> [
7> _Kty=CString,
7> _Ty=CString,
7> _Hasher=std::hash<CString>,
7> _Keyeq=std::equal_to<CString>,
7> _Alloc=std::allocator<std::pair<const CString,CString>>
7> ]
7>D:\My Programs22\MeetSchedAssist\Meeting Schedule Assistant\CalendarSettingsOutlookPage.h(59): message : see reference to class template instantiation 'std::unordered_map<CString,CString,std::hash<CString>,std::equal_to<CString>,std::allocator<std::pair<const CString,CString>>>' being compiled
7>C:\Program Files\Microsoft Visual Studio22\Community\VC\Tools\MSVC.30.30705\include\xhash(111,44): error C2056: illegal expression
7>Done building project "Meeting Schedule Assistant.vcxproj" -- FAILED.
如果我使用 std::map<CString, CString>
它可以工作,但 std::unordered_map<CString, CString>
会抛出上述错误。我的用法调用:
if (m_mapCalendarList.find(strCalendarName) != m_mapCalendarList.end())
if (strCalendarId == m_mapCalendarList[strCalendarName])
m_mapCalendarList.clear();
变量定义在header.
MFC 哈希映射有一些缺点,除了不是 C++ 标准而且不是 portable:
- 不要自动重新计算哈希 table。 填充时甚至无法调整散列大小 table。散列的默认大小 table 可能不适合您。
- 如评论中所述,它们不支持基于范围的 for 或范围算法
- 不可复制,不可自行移动。移动容器可能会有用
- 不支持元素插入的移动语义,这涉及一些开销
对于std::unordered_map
,需要实现hash函数,作为对应的模板参数传入。或者为 CString
专门化标准哈希。但我更喜欢前者。
最好也传递比较函数,执行与语言环境无关的比较。由于使用不了解语言环境的散列,无论如何您都无法拥有语言环境感知地图,但是 CString::operator==
是语言环境感知的。
由于 HashKey
可以使用 LPCSTR
和 LPCWSTR
CMap
,实现自己的 STL 兼容散列是微不足道的。
你可以完全避免处理哈希,而使用std::unordered_map<std::string, std::string>
。但过渡到 std::string
会导致更多变化,我猜。