我最近在处理一个小项目时遇到了一组奇怪的错误。这基本上是导致它的代码:
#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/