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

And*_*kle 6 c++ mfc atl c++20 visual-studio-2022

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

例如:

  • CA2CT
  • CW2T
  • CA2W

错误 C2440:“初始化”:无法从 转换ATL::CA2WATL::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); 
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,rStrProgId可能是诸如 之类的值_T("Word.Application")

上述具体情况错误是:

错误 C2440:“初始化”:无法从 转换ATL::CW2WATL::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);
Run Code Online (Sandbox Code Playgroud)

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

Bar*_*ani 5

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

/permissive-(符合标准)

从 Visual Studio 2019 版本 16.8 开始,该/permissive-选项由 /std:c++latest 选项隐式设置,在版本 16.11 中由 /std:c++20 选项隐式设置。/permissive-需要C++20模块支持。

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

CStringA a { CW2A(L"123") };
Run Code Online (Sandbox Code Playgroud)

在这种情况下,据我了解,符合或不符合没有任何区别。但{}自 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
Run Code Online (Sandbox Code Playgroud)