为什么枚举中的元素数量会改变C ++中私有typedef的可见性?

时间:2010-07-05 01:15:58

标签: c++ enums

对于不太具描述性的问题标题感到抱歉。我不太清楚如何描述这个,希望如果有人能向我解释这个,我可以在以后做得更好。

我即将来到这里并询问为什么以下示例正在运作。它展示了我希望的行为,但我不确定它为什么或是否是标准的,或者我是否对编译器感到幸运。无论如何,在整理一个最小的工作示例发布在这里,我发现它根本没有做我想的。所以这就是......

   struct Foo {
       enum BAR { A, B, C, D, E };
       private: typedef BAR BAR;
   };

   int main(int argc, char* argv[]) {
       int x = (Foo::BAR)42;
       int y = Foo::D;
  }

似乎正在发生的事情以及我非常高兴的是,Foo采用了枚举常量,之后BAR变为私有。我在int y =上没有收到任何错误,但我在Foo::BAR收到int x=私有错误。然而,这似乎仅适用于枚举中的5个或更多常量,删除E并且它们都编译良好,即BAR仍然公开。

这里有什么用?感谢。

(PS。编译器是GCC 4.4.3)

4 个答案:

答案 0 :(得分:6)

我可以验证你的结果有关四个和五个枚举元素......这看起来像一个模糊的GCC错误。

至于“这里有什么用”,这是由于C ++中不同符号命名空间之间的技术性(继承自C)。有关详细信息,请参阅this answer

如果您不希望公开名为BAR的符号,只需省略标记名称:

struct Foo {
    enum { A, B, C, D, E };
};

如果你声明一个命名的公共枚举,那么无论你做什么,即使你使用typedef隐藏名称,外人也可以使用详细说明的类型说明符来访问枚举。试图以这种方式隐藏符号名称是徒劳的:

 struct Foo {
     enum BAR { A, B, C, D, E };
     private: typedef BAR BAR;
 };

 int main(int argc, char* argv[]) {
     int x = (enum Foo::BAR)42;  // works great!
     int y = Foo::D;
}

当枚举名称保持私有时,是否有任何特殊原因要求公共常量?

答案 1 :(得分:2)

typedef名称不应与枚举类型名称冲突。相反,typedef名称应隐藏先前声明的枚举类型名称。由于typedef名称是私有的,因此无法从外部访问

Foo::BAR i; // ERROR, `Foo::BAR` is private

仍然可以使用精心设计的类型说明符

来引用隐藏的公共枚举类型名称
enum Foo::BAR i; // OK

枚举常量本身当然是公开的,在您的示例中应该仍然可以访问。

行为不应该取决于枚举中常量的数量。如果您观察到您描述的依赖关系,那么它必定是编译器中的错误。

答案 2 :(得分:0)

我不愿意说“微软做对了”,但我找不到标准中提倡这种行为的任何内容。据我所知,类型名称Foo :: BAR应该始终可以公开访问。

此行为与MSVC ++没有任何偏差。它总是允许您的代码示例编译而不会出错。我在BAR中尝试了多达26个条目。

我敢说这是gcc中的一个错误。

但是我必须同意已经说过的内容 - 我认为这段代码不值得编译。

答案 3 :(得分:0)

使用G ++ 4.2.1在MacOS X 10.6.4上运行'g ++ -c file.cpp',代码编译时没有呜咽,枚举中包含4和5个元素。添加'-Wall -pedantic'只会触发有关未使用变量x和y的投诉。

如评论(和问题标题)中所述,枚举中的元素数量不应影响行为。对我来说,这种不同的行为有点'错误'(在海湾合作委员会中)。

哪种正确行为更复杂;我不愿意采取强硬立场。平均而言,我赞成'Foo :: BAR'首先被公开,后来的私有typedef应该被忽略或者应该是一个错误。然而,这远不是对行为应该是什么的明确观点 - 我很不确定。