C ++ C2440错误,无法从'std :: _ St​​ring_iterator< _Elem,_Traits,_Alloc>'转换到'LPCTSTR'

时间:2015-12-04 17:45:41

标签: c++

不幸的是,我的任务是编译一个旧的C ++ DLL,以便它可以在Win 7 64位机器上运行。我没有C ++经验。我已经混淆了其他问题,但这个问题困扰了我,我没有在其他地方找到解决方案。以下代码抛出了C2440编译器错误。

错误:“错误C2440:'':无法转换为'std :: _ St​​ring_iterator< _Elem,_Traits,_Alloc>'到'LPCTSTR'“

代码:

#include "StdAfx.h"
#include "Antenna.h"
#include "MyTypes.h"
#include "objbase.h"

const TCHAR* CAntenna::GetMdbPath()
{
    if(m_MdbPath.size() <= 0) return NULL;
    return LPCTSTR(m_MdbPath.begin());
}

“m_MdbPath”在Antenna.h文件中定义为      string m_MdbPath;

任何人可以提供的帮助或指导都会非常有帮助。先感谢您。如果需要,我很乐意提供有关代码的其他详细信息。

2 个答案:

答案 0 :(得分:2)

std :: string有一个.c_str()成员函数,可以完成你正在寻找的东西。它将返回一个const char *(const wchar_t * with std :: wstring)。 std :: string也有一个empty()成员函数,我建议使用nullptr而不是NULL宏。

const TCHAR* CAntenna::GetMdbPath()
{
    if(m_MdbPath.empty()) return nullptr;
    return m_MdbPath.c_str();
}

答案 1 :(得分:1)

解决方案:

const TCHAR* CAntenna::GetMdbPath()
{
    if(m_MdbPath.size() <= 0) return NULL;
    return m_MdbPath.c_str();
}
如果您可以保证您的程序使用MBCS字符集选项(或者如果您使用的是Visual Studio,则字符集选项设置为Not Set),

将起作用,因为{ {1}}字符类型与std::string类型相同。

但是,如果您的构建版本为TCHAR,那么UNICODE字符类型将与std::string类型不同,因为TCHAR被定义为宽字符,而不是单字节字符。因此,返回TCHAR将产生编译器错误。因此,您的原始代码以及返回c_str()的暂定修复可能会起作用,但就使用的类型而言,它在技术上是错误的。

您应该直接使用提供给您的函数的类型 - 如果类型为std::string::c_str(),那么您应该使用基于TCHAR的类型,但同样,TCHAR是一种根据构建类型更改定义的类型。

事实上,如果代码是TCHAR构建并且修复编译器错误,代码将在运行时失败,你转换为UNICODE以保持编译器安静。您不能将字符串指针类型转换为另一个字符串指针类型。转换不是转换,只是转换不会将窄字符串转换为宽字符串,反之亦然。你最终会使用或显示奇怪的字符,更糟糕的是,一个程序随机奇怪的行为和崩溃。

除此之外,您永远不知道何时需要构建DLL的UNICODE版本,因为MBCS构建变得越来越少见。通过原始帖子,DLL的LPCTSTR用法表明是的,这个DLL可能(甚至已经)为UNICODE构建。

您可以使用一些替代解决方案。请注意,其中一些解决方案可能要求您在字符串类型之外进行其他编码更改。如果您正在使用C ++流对象,则可能还需要更改它们以匹配字符类型(例如,TCHARstd::ostream

解决方案1.使用std::wostream,其中要使用的字符串类型取决于构建类型。

例如:

typedef

然后使用#ifdef UNICODE typedef std::wstring tchar_string; #else typedef std::string tchar_string; #endif 代替tchar_string。在MBCS和UNICODE构建之间切换将无需强制转换strin类型,但需要编码更改。

解决方案2.使用std::stringtypedef用作TCHAR模板中的基础字符类型。

例如:

std::basic_string

在您的应用中使用typedef std::basic_string<TCHAR> tchar_string; 。您获得与tchar_string相同的公共接口,这允许您无缝切换MBCS和UNICODE构建(关于字符串类型)。

解决方案3.使用UNICODE构建并完全删除MBCS构建

如果您正在构建的应用程序是新应用程序,则在创建新应用程序时,std::(w)string是默认选项(至少在Visual Studio中)。那么你真正需要做的就是使用UNICODE

这与确保使用std::wstring的原始解决方案相反,但IMO这个解决方案更有意义,如果只有一个构建类型。 MBCS构建变得越来越少,并且基本上应该仅用于遗留应用程序。