c++ - 枚举成员与类名冲突

标签 c++ class enums abstract derived

我最近在处理一个小项目时遇到了一组奇怪的错误。这基本上是导致它的代码:

#include <memory>

enum derivedtype {B, C};

//abstract class
class A{};

class B : public A
{};
class C : public A
{};

int main()
{
  {
    std::unique_ptr<A> myb(new B);
    std::unique_ptr<A> myc(new C);
  }
}

产生此编译器错误:

enumclasserror.cpp: In function ‘int main()’:
  enumclasserror.cpp:15:30: error: ‘B’ does not name a type
  std::unique_ptr<A> myb(new B);
                          ^
  enumclasserror.cpp:16:30: error: ‘C’ does not name a type
  std::unique_ptr<A> myc(new C);

修复是在 new 之后添加 class 关键字:

std::unique_ptr<A> myb(new class B);

现在枚举包含在原始代码中抽象类的头文件中(这使得它更难被发现),但没关系;我从来没有想过枚举的成员会导致实例的创建失败。我真的花了几个小时才找到那个错误。谁能向我解释为什么会这样? new 对枚举有意义吗?

P.S.: 这个错误是一个同事发现的,他使用 clang 提示了 class 关键字。正如您所见,我的 Ubuntu 上的标准 C++ 编译器并没有..

最佳答案

在您的示例中,enum 中的 B 隐藏类 B。该标准的第 3.3.10 节描述了名称隐藏的规则:

A class name (9.1) or enumeration name (7.2) can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope. If a class or enumeration name and a variable, data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.

语言设计者需要设置优先规则,所以他们决定 enum 常量名应该胜出。这条规则看起来很武断,可能是模仿了 C 标准中的一些旧规则。但是,它是标准的一部分,因此每个编译器都必须遵守它。

不用说,让类名与 enum 成员发生冲突是一个非常糟糕的主意。解决此问题的最佳方法是重命名您的类(class)。

关于c++ - 枚举成员与类名冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38111837/

相关文章:

c++ - 是什么阻止 g++ 消除运行时未使用的临时 std::array ?

c++ - 更高类型的别名模板

C++通过具有数组索引的类传递参数/

java - 垃圾收集器是否在 Enum 类型上运行?

C++ 服务示例 - Unicode 转换

c++ - MPI : Percolate a subarray from slave processes to update main array in root/master process

class - 如何为类中介器设置参数?

Java - 如何让类 1 和类 2 互相了解?

c# - 解析多个枚举值(已标记): Reading in a filter type from a query string

c++ - QtDBUS:通过 DBUS 发送枚举