转换为枚举类型需要显式转换(static_cast、C 样式转换或函数样式转换)
Posted
技术标签:
【中文标题】转换为枚举类型需要显式转换(static_cast、C 样式转换或函数样式转换)【英文标题】:Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast) 【发布时间】:2012-01-24 10:04:14 【问题描述】:我需要处理一个用 msvcpp6.0sp6 编写的项目
我没有写项目。我对它的内部工作知之甚少。我确实知道过去可以构建它。
在尝试构建过去成功构建的项目时(不是我)
我得到错误:
Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)
例如: 错误 C2664:“strncpy”:无法将参数 2 从“const unsigned short *”转换为“const char *”
错误 C2664: 'void __cdecl CString::Format(const unsigned short *,...)' : 无法转换参数 1
用于几十个隐式转换。我不能更改代码。如何强制编译器接受隐式转换?
【问题讨论】:
您发布的第一个错误与第二个错误无关。 【参考方案1】:我不能更改代码。我怎样才能强制编译器接受 隐式转换?
您很可能需要首先获得用于代码的相同编译器,然后使用它。
如果我对 unsigned short*
错误的猜测(在对 unwind 答案的评论中)是正确的,那么根本不可能在 Unicode 模式下编译此代码,因为源代码的可移植性不足。抑制转换错误,即使可以通过某些编译器设置,也只会导致代码编译但不起作用。
我希望这也意味着旧 dll 可能与您当前的其余代码不兼容,但如果您到目前为止一直在使用它,那么要么我错了原因,要么否则你不知何故侥幸逃脱。
【讨论】:
谢谢!转移到 asci 模式,它解决了问题。感谢您实际尝试按照我的需要而不是您希望的方式解决问题,【参考方案2】:这听起来很疯狂。
将unsigned short *
与strncpy()
之类的字符串处理函数一起使用最初似乎毫无意义。不过,再想一想,这让我想知道是否有某种“宽字符”配置失败了。如果 strncpy()
被编译器“重新定位”以处理 16 位字符,让它期望 unsigned short *
是有道理的,并且会解释为什么代码会这样传递它。至少“有点”解释,它仍然很奇怪。
【讨论】:
我怀疑错误是因为原始代码是为 ASCII 构建编写的,其中TCHAR
是字符,并且它通过 TCHAR*
到 strncpy
。提问者现在正在尝试为 Unicode 构建相同的源,TCHAR
是 unsigned short
,麻烦。所以改变的不是strncpy
,而是调用代码使用的类型。
@SteveJessop 完全有可能。正如我提到的,这是一个非常古老的项目。我怎样才能强制它按原样构建?
@Nahum:好吧,你可以尝试在 ASCII 模式下编译它(或者窄字符模式,我不记得 MSVC 叫什么了)。这不会对枚举转换做任何事情,但它是一种进步。【参考方案3】:
你不能。 C++ 语言没有定义这样的隐式转换。
Visual C++ 6.0 本身就是一条法则。通过实现一些看起来有点像 C++ 语言的东西,它可能已经接受了这个无效代码。
【讨论】:
VC6 确实是这样的,尽管当时 STL 还是相当新的,至少它拥有它并支持模板,可能就像任何编译器在大多数编译器无法处理它们的时候所做的那样很好。 VC6 是 C++ 作为一种语言最流行的时候的编译器,这可能是因为项目生成向导和您获得的所有示例代码允许您“开始”您的项目。与后来的编译器相比,它可能与 C 更向后兼容,因此允许某些操作无需强制转换。 @CashCow:更重要的是,它与第一个 C++ 标准在同一年发布。想想去年 GCC 版本的 C++11 中有多少错误和不完整的功能。 作为商业编译器供应商,Microsoft 必须考虑破坏现有客户的不合规遗留代码会阻碍新编译器的采用。所以这可能是故意放任的。【参考方案4】:C++ 是一种类型安全的语言。但它允许您通过称为强制转换的邪恶告诉编译器“闭嘴”。
从整数到枚举的强制转换通常是一种必要的“邪恶”强制转换,例如,您不能在枚举中循环,例如,您已经为其提供了有限数量的值。因此,您必须使用整数并将它们转换为枚举。
有时您确实需要将数据构造函数转换为 const char * 而不是 const void * 以便执行指针运算。但是,出于 strcpy 的目的,很难理解为什么要使用未签名的短裤。如果这些是宽字符(并且旧编译器不知道 wchar_t),那么将其强制转换为 const wchar_t * 并在宽字符串副本中使用它可能是“安全的”。您还可以使用 C++ 字符串,即 std::string 和 std::wstring。
【讨论】:
这不是我的代码。这是一个非常非常非常古老的 dll 代码,我必须添加一个函数。我不想碰任何已经有效的东西。 @Nahum:“使用我们当前的工具链编译失败”是“已经工作”的有趣定义;-) @SteveJessop 是的,但如何猜测原始链?更改代码是完全不可能的。 @Nahum:你的情况很荒谬。你有一个二进制数据(一个 dll),你不知道它是如何产生的。不允许您更改它,除非您需要更改它(向源代码添加另一个函数并重新编译)。即使我可以,我也不会帮助某些经理对你施加愚蠢、矛盾的限制。但我很确定不可能从 dll 中恢复精确的编译器版本和构建它的选项。 ... 我想您可以安装 MSVC 6 并调整项目设置,以期生成一个二进制相同的 dll,它告诉您您发现的内容“足够接近”原始设置。但这可能需要数周时间并且仍然失败,最好将时间花在寻找首先签入二进制文件的人而不提供重现它的方法并折磨他们。或者更现实的是,对 dll 使用的数据结构进行逆向工程,从头开始实现新功能,而不涉及旧 dll。【参考方案5】:如果您真的不希望更新源代码以符合 ISO 标准,那么最好的办法是为您的旧代码使用原始 VC++ 6.0 编译器。尤其是因为即使您知道这段代码可以工作,但如果它是用不同的编译器编译的,它将是不同的代码并且可能不再工作。如果使用不同的编译器,任何被利用或无意使用的未定义或实现定义的编译器行为都可能导致问题。
如果您订阅了 MSDN,则可以为此目的下载所有以前版本的 VC++。
【讨论】:
以上是关于转换为枚举类型需要显式转换(static_cast、C 样式转换或函数样式转换)的主要内容,如果未能解决你的问题,请参考以下文章
static_cast, dynamic_cast, const_cast讨论