今天,遇到了一个奇怪的问题,MFC代码中无法将字符字面值赋给CString。
代码中这句为:
CString strNew = _T(',');
结果编译的时候报错:无法将wchar_t转为CString。
这就纳闷了,其他的工程都可以啊,接下来找到CString的头文件,发现了问题:
画红线的宏定义为
#define CSTRING_EXPLICIT explicit
原来,单个字符构造CString的构造函数是显式的(explicit),因此编译器编译 CString strNew = _T(‘,’);时,调用了CString的构造函数,然后发现对应的构造函数是显式的,因此,就直接报错了。这里必须说明一句,这可能是VS编译器不合理的一点,实际上在赋值运算符中,是可以将单个字符赋给CString的,编译器完全可以利用默认构造函数生成strNew对象,再将 _T(‘,’) 赋值给这个strNew;但是,VS编译器优先找到参数相符的构造函数,然后检查到其为explicit,然后直接报错。
那么,如何规避这个错误呢?
- 方法1
//CString在初始化以后,可以用字符字面值进行赋值,此时调用的是=号运算符
CString strNew2;
strNew2 = _T('x');
//显式调用单个字符构造函数,编译无问题
CString strNew3(_T(','));
- 方法2
因为自己其他工程用的很多都没问题,我就仔细对比了一下,发现可以利用宏开关处理一下。
在cstringt.h中,有以下几行宏代码,意思是如果定义了 _ATL_CSTRING_EXPLICIT_CONSTRUCTORS 宏,CSTRING_EXPLICIT 就是 explicit;否则 CSTRING_EXPLICIT 其为空。
刚刚提到了参数为单个字符的CString构造函数前面就加了 CSTRING_EXPLICIT 宏,所以是explicit的。那我工程取消 _ATL_CSTRING_EXPLICIT_CONSTRUCTORS 的定义是不是就好了?带着这样的疑惑,我打开了 framework.h 头文件(pch.h 头文件包含 #include “framework.h”),果然,找到了以下几行
原来在framework.h中定义了宏 _ATL_CSTRING_EXPLICIT_CONSTRUCTORS ,注释掉这一行,再编译即可。