2

有人可以阐明访问 C++ 类中定义的枚举的语义吗?

特别是,为什么枚举成员是通过类名而不是枚举本身来访问的?鉴于 theenum是容器/范围,就像namespaceclass是一样,为什么访问容器的元素时它是一个enum而不是当它是一个时class

给定

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

        int myint;
    };
}

为什么enum1 mynamespace::myclass::enum1and not的完全限定名称是mynamespace::myclass::myenum::enum1

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

它产生了非常奇怪的访问规则,并且当您enum1在不同的枚举中添加新的(此时您必须添加限定符)时使事情变得非常奇怪。

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

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

4

2 回答 2

6

在 C++03 中,与在 C 中一样,anenum不会引入新的作用域。定义的名称进入周围的范围。这可能是一个命名空间,或者一个类。

C++11 添加了作用域枚举和基于枚举。

普通C++03 enum

enum Cpp03 { a, b, c };

基于enumC++11 :

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

我的猜测是你遇到的,一个语言扩展。

于 2012-03-21T23:06:13.670 回答
1

基本答案是,您的“鉴于enum是容器/范围”是完全错误的——根据 C 和 C++, anenum没有建立范围(并且不是容器)

简而言之,enum whatever { a, b, c};

与:

const int a = 0;
const int b = 1;
const int c = 2;

虽然您可以使用enum whatever来定义能够保存该类型值的变量,但它们通常与某些能够保存正确值范围的整数类型并没有太大的不同。

于 2012-03-21T23:05:22.627 回答