为什么可以在作用域外访问枚举类型?

4

为什么你可以在作用域外访问枚举类型,而不能直接访问结构体的成员?这里的作用域是指声明作用域 - 如果我说错了,请纠正。

举个例子:

你可以这样做:

enum colors {red, blue, white};
int color = red;

但您不能这样做:
struct colors {red, blue, white};
int color = red;

谢谢!


1
枚举类型不定义作用域;它们只是常量列表,因此您实际上并没有在“作用域外”访问它们。结构体不是常量列表,而是由多个变量组成的对象。另一方面,作用域枚举…… - gsemac
1
因为标准是这样规定的。这是因为在C语言中就是这样的。从C++的角度来看,关于这个问题就只有这么多了。 - Baum mit Augen
你可以写 enum class colors { red, blue, white };,然后标识符将被限定在枚举名称中。 - M.M
@Squidy,你说的“定义作用域”是什么意思?谢谢大家! - user7920734
或者@CharlieMartin,也许你知道? - user7920734
显示剩余3条评论
2个回答

1
好的,正如其他评论所说,这是因为C++的工作方式。
在早期,我们使用类似以下代码来模拟这样的情况:
class Colors {
  public:
    static int RED = 0;
    static int GREEN = 1;
    static int YELLOW = 2;
}

后来添加了枚举,所以你不需要再写Colors.RED了。这本质上是一种语法糖。

更新

作用域就是程序中可见名称的部分。规则可以简单、复杂或奇怪:C++选择了复杂,JavaScript选择了奇怪。你可以在这里这里看到详细的说明,但这里有一个基本概念。

在C++中,名称在声明它的块中定义。一种块是文件。如果一个名称在文件顶部被声明,那么在声明之后的整个文件中都可以使用。

另一种块由一对大括号{}定义。在大括号内声明的任何东西都会从声明开始一直到封闭的右括号为止被定义。

#include <stdlib>  // copies a bunch of code into the file
int foo = 0;       // declared here, visible to end.

int fn(){
  int bar = 2 ;
  if(bar == 2){
    foo = bar;
    cout << bar << nl;  // gives '2'
    cout << foo << nl;  // still gives '2'
  }
  cout << foo << nl ;  // gives '0'
  cout << bar << nl ;  // compile time error 'bar' not defined
}

为什么?内部的foo隐藏了外部的foo,因此在if块内打印的是内部的那个。 barif块的顶部定义,因此在结束if块的大括号后不再可见(“超出范围”)。

还有更多规则,但我建议在这些链接或好的C++书籍中阅读有关内容。


1
谢谢你!但是你会说“bar”只在fn函数的范围内可见,还是说“bar”只在bar块内可见?再次感谢!我真的很喜欢你的回答。 - user7920734
1
糟糕,您实际上已经将答案链接到我的问题上了 :) - user7920734
1
谢谢。你们是一群很棒的观众,请别忘了给服务器小费。 - Charlie Martin
哦,对于你的问题,答案是“是”。我可能会根据我想强调的内容、前面的对话以及月相来选择不同的表达方式。然而,“bar的作用域”才是更加技术上正确的回答。 - Charlie Martin

0

没有超出范围的空间。enum不像struct那样引入新的作用域。为什么?嗯,为什么不呢。它们是两个完全不同的东西,所以期望一个像另一个一样工作是无意义的。

然而,enum class确实可以这样工作;这个特性被恰当地称为“作用域枚举”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接