为什么枚举中的元素数量会改变 C++ 中私有 typedef 的可见性?
抱歉,问题标题描述性不强。我不太确定如何描述这一点,希望如果有人可以向我解释这一点,我以后可以做得更好。
我正要来这里询问为什么下面的示例有效。它表现出了我所希望的行为,但我不确定为什么或者它是否是标准的,或者我是否只是幸运地使用了编译器。不管怎样,在整理一个最小的工作示例并发布在这里时,我发现它根本没有按照我的想法进行。所以这就是......
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 =
上没有收到错误,但在 int x=
上收到 Foo::BAR
is private 错误。然而,这似乎只适用于枚举中的 5 个或更多常量,删除该 E
一切都可以正常编译,即 BAR
仍然是公共的。
这里有什么工作?谢谢。
(PS.编译器是GCC 4.4.3)
Sorry for the not very descriptive question title. I'm not very sure how to describe this, hopefully I can make it better later if someone can explain this to me.
I was about to come on here and ask why the following example was working. It was exhibiting the behaviour I was hoping for but I wasn't sure why or whether it was standard or whether I just got lucky with the compiler. Anyway, in sorting out a minimal working example to post here I found that it wasn't doing what I thought at all. So here it is ...
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;
}
What seems to be happening, and what I was quite pleased about, is that, Foo takes on the enum constants after which BAR is made private. So I get no error on int y =
but I get a Foo::BAR
is private error at int x=
. However this seems to only work with 5 or more constants in the enum, remove that E
and it all compiles fine, i.e. BAR
remains public.
What's at work here? Thanks.
(PS. Compiler is GCC 4.4.3)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我可以验证您关于四个与五个枚举元素的结果...这看起来像一个不起眼的 GCC bug。
至于“这里的工作原理”,这是由于 C++ 中不同符号命名空间之间的技术问题(继承自 C)。有关更多详细信息,请参阅此答案。
如果您不想公开名为
BAR
的符号,只需省略标记名称:如果您声明一个命名公共枚举,那么无论您做什么,甚至如果您使用 typedef 隐藏名称,则外部人员可以使用详细的类型说明符访问枚举。尝试以这种方式隐藏符号名称是徒劳的:
是否有任何特殊原因您希望常量公开而枚举名称保持私有?
I can verify your results about four vs. five enum elements... this looks like an obscure GCC bug.
As for "what's at work here", it's due to a technicality between different symbol namespaces in C++ (inherited from C). See this answer for more details.
If you don't want a symbol named
BAR
to be exposed, simply omit the tag name:If you declare a named public enum, then no matter what you do, even if you hide the name using a typedef, outsiders can access the enum using an elaborated type specifier. Trying to hide a symbol name in this way is fruitless:
Is there any particular reason you want the constants to be public while the enum name remains private?
typedef 名称不应与枚举类型名称冲突。相反,typedef 名称应该隐藏先前声明的枚举类型名称。由于 typedef 名称是私有的,因此应该无法从外部访问它。
不过,您可以使用详细类型说明符引用隐藏的公共枚举类型名称。
当然,枚举常量本身是公共的,并且应该在您的示例中保持可访问性。
该行为不应取决于枚举中常量的数量。如果您观察到所描述的依赖性,则它一定是编译器中的错误。
The typedef name should not conflict with the enum type name. Instead, the typedef name should hide the previously declared enum type name. Since the typedef name is private, it should be inaccessible from outside
Still, you can refer to the hidden public enum type name by using the elaborate type specifier
The enum constants themselves are, of course, public and should remain accessible in your example.
The behavior should not depend on the number of constants in the enum. If you observe the dependence you describe, it must be a bug in the compiler.
我不想说“微软做对了”之类的话,但我在标准中找不到任何提倡这种行为的内容。据我所知,类型名 Foo::BAR 应始终保持可公开访问。
此行为与 MSVC++ 没有任何偏差。它始终允许您的代码示例编译而不会出现错误。我尝试了 BAR 中最多 26 个条目的所有内容。
我敢说这是 gcc 中的一个错误。
但是我必须同意已经说过的话 - 我认为这段代码不值得编译。
I would hate to say something like "Microsoft got it right" but I can't find anything in the standard that would advocate this kind of behavior. As far as I can tell, the typename Foo::BAR should always remain publicly accessible.
There is no deviation in this behavior from MSVC++. It always allows your code sample to compile without error. I tried everything up to 26 entries in BAR.
I would dare say this is a bug in gcc.
However I have to agree with what has already been said - I don't think this code deserves to be compiled.
在带有 G++ 4.2.1 的 MacOS X 10.6.4 上运行“g++ -c file.cpp”,代码可以顺利编译,枚举中同时包含 4 个和 5 个元素。添加“-Wall -pedantic”只会引发对未使用变量 x 和 y 的抱怨。
正如评论(和问题标题)中所述,枚举中的元素数量不应影响行为。对我来说,这种不同的行为有点“bug”(在 GCC 中)。
哪种行为是正确的,比较复杂;我不愿意对此采取强硬立场。平均而言,我赞成首先将 'Foo::BAR' 声明为公共,然后应该忽略后面的私有 typedef 或者应该是一个错误。然而,这远不是行为应该是什么的明确观点——我非常不确定。
Running 'g++ -c file.cpp' on MacOS X 10.6.4 with G++ 4.2.1, the code compiles without a whimper with both 4 and 5 elements in the enumeration. Adding '-Wall -pedantic' only triggers complaints about unused variables x and y.
As noted in a comment (and the question title), the number of elements in the enumeration should not affect the behaviour. To me, such varying behaviour smacks of 'bug' (in GCC).
Which is the correct behaviour is more complex; I'm loath to take a strong stance on that. On average, I favour 'Foo::BAR' was first declared public and the later private typedef should be ignored or should be an error. However, that is very far from being a definitive view on what the behaviour should be - I am very uncertain.