C++ C2440 错误,无法从 'std::_String_iterator<_Elem,_Traits,_Alloc>' 转换为 'LPCTSTR'
C++ C2440 Error, cannot convert from 'std::_String_iterator<_Elem,_Traits,_Alloc>' to 'LPCTSTR'
不幸的是,我的任务是编译一个旧的C++DLL,以便它能在Win 7 64位机器上运行。我没有任何C++经验。我把其他问题弄得一团糟,但这件事难住了我,我在其他地方也找不到解决办法。以下代码引发了一个C2440编译器错误。
错误:"错误C2440:":无法从'std::_String_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文件中定义为字符串m_MdbPath;
任何人能提供的帮助或指导都是非常有帮助的。提前谢谢。如果需要,我很乐意提供有关代码的更多详细信息。
std::string有一个.c_str()成员函数,它应该可以完成您想要的任务。它将返回一个const char*(const wchar_t*和std::wstring)。std::string还有一个empty()成员函数,我建议使用nullptr而不是NULL宏。
const TCHAR* CAntenna::GetMdbPath()
{
if(m_MdbPath.empty()) return nullptr;
return m_MdbPath.c_str();
}
解决方案:
const TCHAR* CAntenna::GetMdbPath()
{
if(m_MdbPath.size() <= 0) return NULL;
return m_MdbPath.c_str();
}
如果可以保证程序使用MBCS
字符集选项(或者如果使用Visual Studio,则"字符集"选项设置为Not Set
),则会起作用,因为std::string
字符类型与TCHAR
类型相同。
但是,如果您的构建是UNICODE
,那么std::string
字符类型将与TCHAR
类型不同,因为TCHAR
被定义为宽字符,而不是单字节字符。因此,返回c_str()
将给出编译器错误。因此,您的原始代码,加上返回std::string::c_str()
的临时修复可能会起作用,但就所使用的类型而言,这在技术上是错误的。
您应该直接使用提供给函数的类型——如果类型是TCHAR
,那么您应该使用基于TCHAR
的类型,但TCHAR
是一种根据构建类型更改定义的类型。
事实上,如果代码是UNICODE
构建的,那么它在运行时会失败得很惨,为了修复编译器错误,您将其转换为LPCTSTR
以保持编译器安静。不能将字符串指针类型强制转换为其他字符串指针类型。铸造不是转换,仅仅铸造不会将窄弦转换为宽弦,反之亦然。你至少会使用或显示一些奇怪的字符,更糟糕的是,一个程序会出现随机的奇怪行为和崩溃。
除此之外,您永远不知道什么时候真正需要构建UNICODE版本的DLL,因为MBCS构建变得越来越罕见。根据你最初的帖子,DLL对TCHAR
的使用表明,是的,这个DLL可能(甚至已经)是为UNICODE构建的。
您可以使用一些替代解决方案。请注意,其中一些解决方案可能需要在字符串类型之外进行额外的编码更改。如果使用C++流对象,可能还需要更改它们以匹配字符类型(例如,std::ostream
和std::wostream
)
解决方案1。使用typedef
,其中要使用的字符串类型取决于生成类型
例如:
#ifdef UNICODE
typedef std::wstring tchar_string;
#else
typedef std::string tchar_string;
#endif
然后使用CCD_ 20而不是CCD_。在MBCS和UNICODE构建之间切换将在不必强制转换字符串类型的情况下工作,但需要更改编码。
解决方案2。使用typedef
可以使用TCHAR
作为std::basic_string
模板中的基本字符类型
例如:
typedef std::basic_string<TCHAR> tchar_string;
并在您的应用程序中使用tchar_string
。您获得了与std::(w)string
相同的公共接口,这允许您在MBCS和UNICODE构建之间无缝切换(就字符串类型而言)。
解决方案3。使用UNICODE构建并完全放弃MBCS构建
如果您正在构建的应用程序是一个新应用程序,那么UNICODE
是创建新应用程序时的默认选项(至少在Visual Studio中是这样)。那么您真正需要做的就是使用std::wstring
。
这与确保使用MBCS
的原始解决方案有点相反,但如果只有一种构建类型,则IMO此解决方案更有意义。MBCS构建变得越来越罕见,基本上应该只用于遗留应用程序。
- 如何将 std::ifstream 转换为 std::basic_istream<CharT, Traits>&?
- 组件对象模型 (COM):IMalloc::Alloc 在哪里分配内存?
- 获取错误:在抛出"std::bad::alloc"的实例后终止调用 what(): std::bad_alloc
- cv::D ataType<> 与 cv::traits::Type<>
- CGAL:Hausdorff距离不良Alloc
- C STD ::初始化类对象中的Alloc错误错误
- 尝试解决HackerBank上的BFS挑战时出现错误的alloc异常
- 类型 traits,用于检查参数包中的所有类型是否都是可复制构造的
- 为背包算法使用向量时抛出了错误的alloc
- 错误 C2228:'.Alloc'左侧必须具有类/结构/联合
- 为什么 cocos2d 和 libdispatch.dylib 如此频繁地调用 alloc
- 对采用"traits"模板参数的对象进行单元测试
- 在分配器中使用new函数和*alloc函数时,它们之间有区别吗
- 为什么'has_construct<Alloc, T, Args...>::value'在gcc(false)和clang(true)上给出不同的值?
- 如何追踪"tcmalloc : large alloc .... "
- C++:是否有一个包含各种函数的traits类来操作以零结尾的char*和wchar_t*字符串
- c++中的Alloc数组,c#中的free数组
- Cppcheck认为在alloc和dealloc中存在不匹配
- 无法将'SEXP'转换为"Rcpp::traits::input_parameter<double>
- C++:使用内部typedef(如果traits类或默认值中可用)