error C2440: ‘initializing’ : cannot convert from ‘PCTSTR’ to ‘ATL::CStringT’

CAtlString是可以在ANSI和UNICODE之间转换的,例如CAtlStringA strSomething = lpszSomething,这里的lpszSomething是wchar_t字符串类型。

可是你会发现这种语句有时候可以编过,有时候又不可以编过,非要用CAtlStringA strSomething(lpszSomething):
error C2440: 'initializing' : cannot convert from 'PCTSTR' to 'ATL::CStringT<BaseType,StringTraits>'
with
[
BaseType=char,
StringTraits=ATL::StrTraitATL<char,ATL::ChTraitsCRT<char>>
]
Constructor for class 'ATL::CStringT<BaseType,StringTraits>' is declared 'explicit'
with
[
BaseType=char,
StringTraits=ATL::StrTraitATL<char,ATL::ChTraitsCRT<char>>
]

遇到这种问题真是抑郁,明知是2B的问题却不明真相,每次遇到只能退缩改为显式构造。

这次深究了一下,CAtlString的实现会落在CStringT上,CStringT的构造函数对于YCHAR(即另一种字符类型,CStringT把自身的字符类型定义为XCHAR)作参数如下:
CSTRING_EXPLICIT CStringT( __in_z_opt const YCHAR* pszSrc )

注意这里有个CSTRING_EXPLICIT宏,它被定义为:
#ifdef _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#define CSTRING_EXPLICIT explicit
#else
#define CSTRING_EXPLICIT
#endif

原来是有_ATL_CSTRING_EXPLICIT_CONSTRUCTORS宏定义的时候不同类型的字符串转换需要显式调用构造函数,看看stdafx.h里还真有这个宏定义:
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit

删掉这个宏定义就能使用CAtlStringA strSomething = lpszSomething这类用法了。为什么需要这么一个宏去控制这类构造函数需要显式调用?

MS说得很清楚了,防止无心的字符串转换。_ATL_CSTRING_EXPLICIT_CONSTRUCTORS

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据