当指定 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 一起使用时遇到问题:
例如:
CA2CT
CW2T
CA2W
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
我在尝试将 C++20 与 Visual Studio 2022 一起使用时遇到问题:
例如:
CA2CT
CW2T
CA2W
error C2440: 'initializing': cannot convert from
ATL::CA2W
toATL::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
toATL::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 forC++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