错误 C2327:不是类型名称、静态或枚举数 - 仅限 MSVC14

Posted

技术标签:

【中文标题】错误 C2327:不是类型名称、静态或枚举数 - 仅限 MSVC14【英文标题】:Error C2327: not a type name, static, or enumerator - MSVC14 only 【发布时间】:2016-04-29 12:14:34 【问题描述】:

我有一个在 GCC 5.3、MSVC12 和 clang 3.7 中编译良好的代码。但是,它在 MSVC14 中没有。它以某种方式尝试使用成员而不是命名空间,我真的不知道这里发生了什么。

#include <QtCore/qglobal.h>

namespace data

class Bar ;


struct Parent

    int data;
;

namespace other

struct Foo : public Parent

    void foo(data::Bar);
;


void other::Foo::foo(data::Bar)  

int main()

    return 0;

结果

    cl -c -nologo -Zc:wchar_t -FS -Zc:strictStrings -Zc:throwingNew -Zi -MDd -GR -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -EHsc /Fddebug\bug.pdb -DUNICODE -DWIN32 -DWIN64 -DQT_QML_DEBUG -DQT_CORE_LIB -I..\bug -I. -IE:\Qt\Qt5.6.0\5.6\msvc2015_64\include -IE:\Qt\Qt5.6.0\5.6\msvc2015_64\include\QtCore -Idebug -IE:\Qt\Qt5.6.0\5.6\msvc2015_64\mkspecs\win32-msvc2015
main.cpp
..\bug\main.cpp(21): error C2327: 'Parent::data': is not a type name, static, or enumerator

请注意,这是一个 Qt 项目,如果我删除包含,它可以编译。基本上,如果我更改此代码中的任何内容,它就可以编译。例如这有效:

namespace other

void Foo::foo(data::Bar)  

如果我重命名成员变量数据或命名空间数据,它也可以工作。但是我无法在现实中进行这些更改,声明是由 qmake 生成的代码,重命名命名空间不是一种选择。

这可能是编译器错误吗?有什么想法吗?

【问题讨论】:

【参考方案1】:

在线21

void other::Foo::foo(data::Bar)  

data 是一个模棱两可的标识符:

数据命名空间。 类Parent的数据成员变量。 xutility 中定义的数据函数之一包括近线1484(在标准安装中,它位于C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xutility)。 xutility 间接包含在 #include &lt;QtCore/qglobal.h&gt; 中。

似乎删除这 3 个中的任何一个都可以使编译器解决歧义。您肯定没有其他编译器的问题,因为您在xutility 标头中没有数据函数,甚至xutility 文件都不存在。

为了解决歧义,将第 21 行替换为:

void other::Foo::foo(::data::Bar)  

如果以后还有其他地方必须解决歧义,请根据上下文使用其中之一:

::data Parent::data this-&gt;data

【讨论】:

【参考方案2】:

data 是模棱两可的,因为 Parent 已经有一个该名称的成员,并且编译器尝试解析其不存在的成员 Bar,它是一个变量(将其视为对象)而不是一个类或命名空间。

我建议重命名命名空间以避免歧义和混淆,例如。 G。使用 CamelCase (Data),因为应该为变量/实例/对象保留小写名称。如果这不是一个选项,请尝试通过全局命名空间访问它:

void foo(::data::Bar);

【讨论】:

我只是很困惑为什么编译时不包含包含?我仍然不相信这个声明实际上是模棱两可的。 如果删除 Qt 包含允许它构建,那么 Qt 必须提供一些导致歧义的数据声明,因为您无法更改 Qt,您需要在代码中使用不同的标识符。 @nate OP 说重命名 data 命名空间工作。因此,OP 的namespace data 声明与Qt 中没有冲突。我的猜测是 Qt 包含可能会改变编译器的行为。 解决方案是不要重命名data(既不是命名空间也不是变量)。如果包含的库发生名称冲突怎么办? C++ 提供了解决歧义的一切,因此解决方案就是解决歧义。使用::dataParent::datathis-&gt;data 明确您的工作。 有很多“解决方案”,通过使用范围解析或this-&gt; 来解决歧义可能比重命名命名空间更好。但是歧义仍然是 Qt 的错。它可能类似于在全局命名空间中的匿名命名空间中使用标识符 data,然后在从全局命名空间查找时隐藏 data 命名空间。

以上是关于错误 C2327:不是类型名称、静态或枚举数 - 仅限 MSVC14的主要内容,如果未能解决你的问题,请参考以下文章

Java 枚举类型必须定义在静态类中

错误“名称空间'System.Web'中不存在类型或名称空间名称'Script'”背后是不是有解释

具有类名的数据成员

错误 CS0234 名称空间“MvvmCross”中不存在类型或名称空间名称“Platforms”(您是不是缺少程序集引用?)

错误 1 未能找到类型或命名空间名称“Form1”(是不是缺少 using 指令或程序集引用?)

错误 CS0246:找不到类型或命名空间名称“Player”(您是不是缺少 using 指令或程序集引用?) Unity [关闭]