C++中枚举访问语义背后的基本原理

Mah*_*dsi 2 c++ enums rationale

有人能否对访问C++中的类中定义的枚举的语义有所了解?

特别是,为什么枚举成员是通过类的名称而不是枚举本身来访问的?鉴于enum在容器/范围,就像namespaceclass被,为什么访问区别对待容器的元素时,这是一个enum比它的一个时class

特定

namespace mynamespace
{
    class myclass
    {
    public:
        enum myenum
        {
            enum1,
            enum2
        };

        int myint;
    };
}
Run Code Online (Sandbox Code Playgroud)

为什么是完全限定名称enum1 mynamespace::myclass::enum1而不是mynamespace::myclass::myenum::enum1

虽然后者"有效",但它不是"推荐"的方式来调用它,而一些编译器会在那里发出警告.恕我直言,它不仅应该是正确的,而且它也应该是访问它的唯一方式.

它构成了非常奇怪的访问规则,并且当你enum1在另一个枚举中添加一个新东西时会让事情变得非常奇怪(此时你必须添加限定符).

真的,它打败了枚举的目的.枚举的成员实际上是更多的成员,而不是枚举,我必须说我发现其他语言(例如C#)的行为更为可取.

我想这是为了保持与C的兼容性,但是我不明白为什么要求访问语义中的枚举名称是更好的选择...我想让名可选是保留C兼容性的选项.

Che*_*Alf 6

在C++ 03中,与在C中一样,a enum不会引入新的范围.定义的名称将进入周围范围.可能是命名空间或类.

C++ 11添加了作用域枚举和基础枚举.

普通C++ 03 enum:

enum Cpp03 { a, b, c };
Run Code Online (Sandbox Code Playgroud)

基于enum C++ 11 :

enum Cpp11Based: long { a, b, c };
Run Code Online (Sandbox Code Playgroud)

C++ 11 作用域enum(作为名称的作用域,如在您的示例中):

enum class Cpp11Scoped1 { a, b, c };
enum struct Cpp11Scoped2 { a, b, c };
Run Code Online (Sandbox Code Playgroud)

最后两种形式是等效的,并允许写作,例如Cpp11Scoped1::a.

最后,作用域enum可以基于(指定名称的基础类型,即大小和签名):

enum class Cpp11ScopedAndBased: long { a, b, c };
Run Code Online (Sandbox Code Playgroud)

一些C++ 03编译器,包括Visual C++,也为普通的C++ 03提供了范围功能enum.

我的猜测是你遇到的,语言扩展.