有人能否了解一下用于访问C ++中类中定义的枚举的语义?
特别是,为什么枚举成员是通过类的名称而不是枚举本身来访问的?鉴于enum
是容器/范围,就像namespace
和class
一样,为什么访问容器的元素时处理enum
而不是它的时候。一个class
?
鉴于
namespace mynamespace
{
class myclass
{
public:
enum myenum
{
enum1,
enum2
};
int myint;
};
}
为什么enum1
mynamespace::myclass::enum1
而非mynamespace::myclass::myenum::enum1
的完全限定名称?
虽然后者“有效”,但它不是“推荐”的方式来调用它,而一些编译器会在那里发出警告。恕我直言,它不仅应该是正确的,而且它也应该是访问它的唯一方式。
它实现了非常奇怪的访问规则,并且当您在不同的枚举中添加新的enum1
时会使事情变得非常奇怪(此时您必须添加限定符)。
真的,它违背了枚举的目的。枚举的成员实际上是更多的成员,而不是枚举,我必须说我发现其他语言(例如C#)的行为更为可取。
我想这是为了保持与C的兼容性,但我不明白为什么要求访问语义中的枚举名称是更好的选择...我想要制作类 name optional是保留C兼容性的选项。
答案 0 :(得分:6)
在C ++ 03中,与在C中一样,enum
不会引入新范围。定义的名称将进入周围范围。可能是命名空间或类。
C ++ 11添加了范围内的枚举和基于枚举。
普通C ++ 03 enum
:
enum Cpp03 { a, b, c };
C ++ 11 基于enum
:
enum Cpp11Based: long { a, b, c };
C ++ 11 作用域enum
(作为名称的作用域,如您的示例所示):
enum class Cpp11Scoped1 { a, b, c };
enum struct Cpp11Scoped2 { a, b, c };
最后两种形式是等效的,并允许写作,例如Cpp11Scoped1::a
。
最后,范围enum
可以基于(为名称指定基础类型,即大小和签名):
enum class Cpp11ScopedAndBased: long { a, b, c };
一些C ++ 03编译器,包括Visual C ++,也为普通的C ++ 03 enum
提供了范围功能。
我的猜测是你遇到了什么,语言扩展。
答案 1 :(得分:1)
基本答案是你的“鉴于enum
是容器/范围”是完全错误的 - 根据C和C ++,enum
不建立范围(而不是容器)。
简而言之,enum whatever { a, b, c};
与以下内容完全不同:
const int a = 0;
const int b = 1;
const int c = 2;
虽然您可以使用enum whatever
来定义能够保存该类型值的变量,但它们通常与能够保持正确值范围的某种整数类型完全不同。