使用同名的类和枚举?

cai*_*rol 11 c++ enums class

我有一个类和一个具有相同名称的枚举值.在课堂内我想使用枚举,这会产生错误.有没有办法在重命名或移动到不同的命名空间的情况下使用枚举?

例:

namespace foo {
    enum bar {
        BAD
    };

    class BAD {
        void worse () {
            bar b = BAD; // error
        }
    };
};
Run Code Online (Sandbox Code Playgroud)

Dav*_*eas 9

这是如何执行名称查找的棘手部分之一.

C++中有两个标识符范围,一个用于类类型和一般标识符范围.枚举值BAD驻留在通用标识符范围中,而类类型BAR驻留在类标识符范围中.这就是为什么允许你同时拥有枚举值和具有相同名称的类的原因:两个名称都不会发生冲突.

在BAD类中,标识符查找规则将在找到枚举之前找到类BAD,从而找到错误.现在,如果您完全限定标识符,则名称查找将首先检查全局标识符范围并匹配枚举值.在另一端,您必须添加structor class关键字来声明BAD类型的变量.

namespace foo {
   enum bad { BAD; };
   class BAD {
      void worse() { bad b = ::foo::BAD; } // fully qualified will match the enum
   };
}
int main() {
   // foo::BAD b;    // error, foo::BAD is an enum, not a type
   class foo::BAD b; // correct
}
Run Code Online (Sandbox Code Playgroud)

现在,我会反对这种用法.重复使用这样的标识符通常不是一个好主意.代码将更复杂,并且可能会对随意读者产生误导(相同的非限定标识符在不同的上下文中使用时指的是不同的东西).如果名称确实需要BAD,请考虑为类或枚举使用封闭的命名空间或类(更喜欢那里的枚举).


APr*_*mer 5

 bar b = foo::BAD;
Run Code Online (Sandbox Code Playgroud)

或者如果您在全局命名空间中

 bar b = ::BAD;
Run Code Online (Sandbox Code Playgroud)

但是这个名称重载不是我推荐的.C++ 0X允许

 bar b = bar::BAD;
Run Code Online (Sandbox Code Playgroud)

如果对C++ 0X的依赖是可接受的,那么这是一个更好的解决方案.

正如所承诺的,解释

9.1/2

如果在声明了同名对象,函数或枚举器的作用域中声明了类名,那么这两个声明都在作用域中,只能使用elaborated-type-specifier来引用该类(3.4.4) )

阐述了式说明符的形式

class BAD b;
Run Code Online (Sandbox Code Playgroud)

这是为了与C兼容,其中标签名称在不同的名称空间中,如果想要在没有精心设计的类型说明符的情况下使用它们,则必须是[i] typedef [/ i] ed.(一个众所周知的函数示例是Unix中的struct stat和function stat).

这解释了为什么重载名称以指定类和枚举器是可能的.BAD在这里指定类的原因是类的名称也被定义到类作用域中,并且在成员函数定义中搜索的作用域按顺序排列: - 成员函数作用域 - 类作用域 - 包含该作用域的名称空间类定义

在类范围内找到BAD,因此永远不会搜索名称空间foo.