【问题标题】:use class and enum with same name?使用同名的类和枚举?
【发布时间】:2011-01-16 02:10:55
【问题描述】:

我有一个同名的类和一个枚举值。在类中,我想使用给出错误的枚举。有没有办法使用枚举而不重命名或移动到不同的命名空间?

例子:

namespace foo {
    enum bar {
        BAD
    };

    class BAD {
        void worse () {
            bar b = BAD; // error
        }
    };
};

【问题讨论】:

  • 为了提高可读性,我强烈建议为enumclass 选择不同的名称。请记住,更好的目标是开发易于维护的软件,而不是调用编译器或语言中的微妙之处。

标签: c++ class enums


【解决方案1】:

这是执行名称查找的那些棘手部分之一。

C++ 中有两种标识符作用域,一种用于类类型和通用标识符作用域。枚举值 BAD 位于通用标识符范围内,而类类型 BAR 位于类标识符范围内。这就是为什么您可以同时拥有一个枚举值和一个具有相同名称的类的原因:两个名称不会冲突。

在 BAD 类中,标识符查找规则将在找到枚举之前找到 BAD 类,从而导致错误。现在,如果您完全限定了标识符,那么名称查找将首先检查全局标识符范围并匹配枚举值。在另一端,您必须添加 structclass 关键字来声明 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
}

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

【讨论】:

    【解决方案2】:
     bar b = foo::BAD;
    

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

     bar b = ::BAD;
    

    但我不建议重载名称。 C++0X 将允许

     bar b = bar::BAD;
    

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

    如约而至,解释

    9.1/2

    如果在一个范围内声明了一个类名,其中还声明了一个同名的对象、函数或枚举器,那么这两个声明都在范围内,该类只能使用一个详细类型来引用-说明符 (3.4.4)

    详细类型说明符是形式

    class BAD b;
    

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

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

    在类范围内发现 BAD,因此从不搜索命名空间 foo。

    【讨论】:

    • 有人想知道我是否尝试过。我使用了 3 个不同的编译器,包括 como。规则很晦涩,如果我记得有时间,我会给出更完整的解释,并附上参考资料。
    【解决方案3】:

    不,没有办法做到这一点。您应该使用有效的标识符。有效标识符意味着您必须能够识别它。 :)

    【讨论】:

      【解决方案4】:

      这在 VS2008 中有效,但会发出警告:

      bar b = bar::BAD;
      

      这不是我可以推荐的。

      您应该将枚举放在 foo 内的另一个命名空间中,并使用新命名空间限定 barBAD

      【讨论】:

      • 这是 C++0X 语法,如果可用,它是首选解决方案。我的解决方案是 C++03 语法(但使用晦涩难懂的规则)。
      猜你喜欢
      • 2012-11-05
      • 1970-01-01
      • 1970-01-01
      • 2011-03-06
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多