在 VS2022 (17.0.6) 中使用 C++20 时缺少 MFC CString 运算符 ==() 重载

cri*_*ell 5 c++ mfc c++20

更新:此问题已在 VS2022 v17.2 Preview 1 中修复

CString当我将 MFC 项目设置为使用 C++20 时,在将字符串文字与实例进行比较时遇到错误。

例如:

CString s1 = _T("s1");
    
// this works
if (s1 == _T("s1")) {
  cout << "Match!"
}

// this generates a compiler error 
if (_T("s1") == s1) {
  cout << "Match!";
}
Run Code Online (Sandbox Code Playgroud)

根据CStringT文档,有很多==重载:

friend bool operator==(const CStringT& str1, const CStringT& str2) throw();
friend bool operator==(const CStringT& str1, PCXSTR psz2) throw();
friend bool operator==(const CStringT& str1, PCYSTR psz2) throw();
friend bool operator==(const CStringT& str1, XCHAR ch2) throw();
-> friend bool operator==(PCXSTR psz1, const CStringT& str2) throw();
friend bool operator==(PCYSTR psz1, const CStringT& str2,) throw();
friend bool operator==(XCHAR ch1, const CStringT& str2,) throw();
Run Code Online (Sandbox Code Playgroud)

我标记了我认为应该找到的那个。然而,它似乎甚至没有考虑超载:

error C2666: '==': 3 overloads have similar conversions
message : could be 'bool operator ==(const D2D1_RECT_U &,const D2D1_RECT_U &)'
message : or       'bool operator ==(const D2D1_SIZE_U &,const D2D1_SIZE_U &)'
message : or       'bool operator ==(const DEVPROPCOMPKEY &,const DEVPROPCOMPKEY &)'
message : or       'bool operator ==(const DEVPROPKEY &,const DEVPROPKEY &)'
message : or       'int operator ==(const PROPERTYKEY &,const PROPERTYKEY &)'
message : or       'bool operator ==(const GUID &,const GUID &)'
message : or       'bool ATL::operator ==(const 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>>> &) noexcept' [found using argument-dependent lookup]
message : or       'bool ATL::operator ==(const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>> &,const wchar_t *) noexcept' [found using argument-dependent lookup]
message : or       'bool ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::operator ==(const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>> &,const char *)' [found using argument-dependent lookup]
message : or       'bool ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::operator ==(const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>> &,wchar_t) noexcept' [found using argument-dependent lookup]
message : or 'bool operator ==(const GUID &,const GUID &)' [synthesized expression 'y == x']
message : or 'bool ATL::operator ==(const 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>>> &) noexcept' [synthesized expression 'y == x']
message : or 'bool ATL::operator ==(const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>> &,const wchar_t *) noexcept' [synthesized expression 'y == x']
message : or 'bool ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::operator ==(const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>> &,const char *)' [synthesized expression 'y == x']
message : or 'bool ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::operator ==(const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>> &,wchar_t) noexcept' [synthesized expression 'y == x']
message : or 'int operator ==(const PROPERTYKEY &,const PROPERTYKEY &)' [synthesized expression 'y == x']
message : or 'bool operator ==(const DEVPROPKEY &,const DEVPROPKEY &)' [synthesized expression 'y == x']
message : or 'bool operator ==(const DEVPROPCOMPKEY &,const DEVPROPCOMPKEY &)' [synthesized expression 'y == x']
message : or 'bool operator ==(const D2D1_SIZE_U &,const D2D1_SIZE_U &)' [synthesized expression 'y == x']
message : or 'bool operator ==(const D2D1_RECT_U &,const D2D1_RECT_U &)' [synthesized expression 'y == x']
message : or       'built-in C++ operator==(const wchar_t [3], const wchar_t [3])'
message : or       'built-in C++ operator==(const wchar_t *, const wchar_t *)'
message : while trying to match the argument list '(const wchar_t [3], CString)'
Run Code Online (Sandbox Code Playgroud)

于是我查看了头文件( cstringt.h),发现一堆函数friend,包括我标记的函数,都被#ifdef'd掉了,因为__cpp_lib_three_way_comparison' #defined'。

宇宙飞船操作员是否以某种方式使一堆友元功能变得不必要了?如果是这样,解决办法是什么?我知道我可以将比较更改为,s1 == _T("s1")但我喜欢在左侧有一个常量表达式,以防我不小心使用=而不是==

cri*_*ell 2

Microsoft 根据https://developercommunity.visualstudio.com/t/Missing-comparison-operators- Between-LPC/1614285 在 17.2 Preview 1 中修复了此问题。