当指定 C++20 时,无法在 Visual Studio 2022 中使用 CA2CT 和 CW2T

Unable to use CA2CT and CW2T in Visual Studio 2022 when C++20 is specified

我在尝试将 C++20 与 Visual Studio 2022 一起使用时遇到问题:

例如:

error C2440: 'initializing': cannot convert from ATL::CA2W to 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").

这样的值

以上具体情况错误为:

error C2440: 'initializing': cannot convert from ATL::CW2W to ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>


其他代码片段示例:

示例 2

CString strCalendarName = CA2CT(pName->GetText(), CP_UTF8);

(pName->GetText()的值为const char *).


更新

按照@Inspectable 所说的操作解决了一个问题。

其他无法编译的(示例)是:

std::string s1 = CT2A(strNameText);
CString strStudent1 = CA2CT(pElement1->GetText(), CP_UTF8);

还有其他编译问题,但我觉得它们超出了这个问题的范围。

问题显然与 /permissive- 编译器选项有关。如果选择 c++20,编译器会强制使用 /permissive- 选项。

/permissive- (Standards conformance)

The /permissive- option is implicitly set by the /std:c++latest option starting in Visual Studio 2019 version 16.8, and in version 16.11 by the /std:c++20 option. /permissive- is required for C++20 Modules support.

启用/permissive-/std:c++20后,编译器将不允许CStringA a = CW2A(L"123");(我想是因为CW2A/CA2W使用转换运算符到returnTCHAR*缓冲到CString),所以需要{}初始化

CStringA a { CW2A(L"123") };

在这种情况下,据我所知,无论是否符合,都没有区别。但是从 c++11 开始,{} 更适合用于初始化。例如它可以检查收缩转换,它与其他初始化形式更一致:

char c = 256;//compiles with warning, narrowing conversion
char c {256};//won't compile
char c[] = { 1,2 };//ok
auto c {256};//compiles, auto -> int c
auto c = {256};//std::initializer_list, cout << *c.begin();
foo::foo(int i) : m_int{ i } {};//member initialization list
RECT rc{};//set all members to zero