枚举成员与类名冲突
Enum Members conflict with class names
我最近在做一个小项目时产生了一组奇怪的错误。这基本上是导致它的代码:
#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);
现在枚举包含在原始代码中抽象类的头文件中(这使得它更难被发现),但没关系;我从来没有想到枚举的成员会导致实例的创建失败。我花了好几个小时才找到那个bug。有人能解释一下为什么会这样吗?new对枚举有意义吗?
注::该错误是由使用clang的同事发现的,clang建议使用class关键字。正如你所看到的,我的Ubuntu上的标准c++编译器没有…
在您的示例中,B
from enum
隐藏了B
类。标准的第3.3.10节描述了名称隐藏的规则:
类名(9.1)或枚举名(7.2)可以通过在同一作用域中声明的变量名、数据成员名、函数名或枚举数名来隐藏。如果类或枚举名与变量、数据成员、函数或枚举数在同一作用域中以相同的名称声明(以任何顺序),则类或枚举名将隐藏在变量、数据成员、函数或枚举数名可见的地方。
语言设计者需要设置优先级规则,所以他们决定enum
常量名应该胜出。这个规则看起来很武断,可能是模仿C标准中的一些旧规则。然而,它是标准的一部分,所以每个编译器都必须遵守它。
不用说,使类名与enum
成员冲突是一个非常糟糕的主意。此问题的最佳解决方案是重命名您的类。
我不知道你还期待什么。
首先,引入了名为B
和C
的整型常量。当然,您不能new
这些。这就像写new 42
。
然后,引入了具有相同名称的类型。好吧,这是允许的,但为了使用它们,您现在必须将它们称为class B
和class C
(或struct B
和struct C
),正如您所发现的那样。
不要对不同的东西使用相同的名称
相关文章:
- 枚举成员与静态 int 成员?
- 从类访问枚举成员
- 枚举成员不是类型错误
- std::映射键作为模板化结构与枚举成员
- 设置类的枚举成员无效地使用"枚举"
- 如何访问结构和枚举成员形成一类
- 是否可以在 constexpr 函数中遍历枚举成员,因此值为 constexpr
- 获取 [枚举成员?] 的封闭类型
- 如何使用 SWIG 枚举枚举成员
- 通过int值访问枚举成员
- '='应初始化所有枚举成员或仅初始化第一个枚举成员;
- 为什么可以获取此枚举成员值,而不必先深入研究嵌套枚举
- 将具有枚举成员的非托管结构封送到 C#
- 为类模板的枚举成员定义 std::hash
- 缩短C++枚举成员的路径(使用 typedef 或 typename),以用作模板参数
- C++类枚举成员变量
- 检查是否已定义枚举成员
- 为什么要使用这段代码来获取枚举成员的数量?
- 使用枚举成员模板化成员函数
- 枚举成员与类名冲突