我在尝试将C++20与Visual Studio 2022配合使用时遇到问题:
例如:
CA2CT
CW2T
CA2W
错误C2440:"正在初始化":无法从ATL::CA2W
转换为ATL::CStringT<wchar_t,StrTraitMFC<wchar_t,ATL::ChTraitsCRT<wchar_t>>>
如果我恢复到C++17就可以了。
这是为什么呢?
下面是一个例子:
CLSID AppCLSID ;
if (SUCCEEDED(::CLSIDFromProgID(CT2W(rstrProgID), &AppCLSID) ) )
{
LPOLESTR pszName = NULL ;
if (SUCCEEDED(::ProgIDFromCLSID(AppCLSID, &pszName) ) )
{
CString strAppID = CW2T(pszName);
}
}
请注意,rStrProgId
可以是类似_T("Word.Application")
的值。
上述特定情况下的错误为:
错误C2440:"正在初始化":无法从ATL::CW2W
转换为ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>
其他代码片段作为示例:
示例2
CString strCalendarName = CA2CT(pName->GetText(), CP_UTF8);
(the pName->GetText()
的值为const char *)
。
更新
做@Inspectable所说的事情可以解决一个问题。
其他无法编译的示例有:
std::string s1 = CT2A(strNameText);
CString strStudent1 = CA2CT(pElement1->GetText(), CP_UTF8);
还有其他编译问题,但我觉得它们超出了这个问题的范围。
2条答案
按热度按时间fjaof16o1#
此问题显然与
/permissive-
编译器选项有关。如果选择c20,则编译器强制/permissive-
选项。/permissive-
(Standards conformance)从Visual Studio 2019版本16.8开始,
/permissive-
选项由/std:c最新选项隐式设置,在版本16.11中由/std:c++20选项隐式设置。C++20
模块支持需要/permissive-
。启用
/permissive-
或/std:c++20
后,编译器将不允许CStringA a = CW2A(L"123");
(我认为是因为CW2A/CA2W
使用转换操作符将TCHAR*
缓冲区返回到CString
),因此需要初始化{}
在这种情况下,就我的理解,一致性和不一致性没有什么区别,但是从c++11开始,
{}
是初始化的首选,例如它可以检查收缩转换,并且它与其他初始化形式更加一致:xzlaal3s2#
我认为这是一个更有历史意义的问题。AFAIK这涉及到
CString
类的隐式处理(隐式操作符:operator LPCTSTR()
等例如与std::string
的可能有意显式的.c_str()
等相反)。[可能相关的主题:网站]https://aras-p.info/blog/2008/10/09/implicit-to-pointer-operators-must-die/ ]
这导致了一个必需的"双重转换"/"双重转换"(很抱歉用了不确切的术语:()从RHS到LHS(
CString
),MSVC一直草率地接受它(就像许多其他令人讨厌的草率的MSVC处理一样),然而,例如gcc很长一段时间(永远?)一直不允许(可能是由于语言规范的要求),导致在尝试使用gcc进行某些到CString
的转换时失败(最好不要问我是如何知道的)。这里的问题应该可以通过以下操作解决😔 ). The issue here should be resolvable by doing或
(BTW哪个比较好?
.m_psz
是实现细节(特定成员),但有趣的是它与T无关static_cast<LPCTSTR>
不特定于实现,但特定于T)
尽管如此,正如其他地方所评论的,这些都是C++规范更改开关所需的源代码更改(可能很多),尽管这是使现有的[不完全精确的]代码适合其他(通常更严格/精确的)规范/环境的相当常见的事情。