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> 会抛出上述错误。我的用法调用:

变量定义在header.

MFC 哈希映射有一些缺点,除了不是 C++ 标准而且不是 portable:

  • 不要自动重新计算哈希 table。 填充时甚至无法调整散列大小 table。散列的默认大小 table 可能不适合您。
  • 如评论中所述,它们不支持基于范围的 for 或范围算法
  • 不可复制,不可自行移动。移动容器可能会有用
  • 不支持元素插入的移动语义,这涉及一些开销

对于std::unordered_map,需要实现hash函数,作为对应的模板参数传入。或者为 CString 专门化标准哈希。但我更喜欢前者。

最好也传递比较函数,执行与语言环境无关的比较。由于使用不了解语言环境的散列,无论如何您都无法拥有语言环境感知地图,但是 CString::operator== 是语言环境感知的。

由于 HashKey 可以使用 LPCSTRLPCWSTR CMap,实现自己的 STL 兼容散列是微不足道的。


你可以完全避免处理哈希,而使用std::unordered_map<std::string, std::string>。但过渡到 std::string 会导致更多变化,我猜。