【问题标题】:Rationale behind enum access semantics in C++C++ 中枚举访问语义背后的基本原理
【发布时间】:2012-04-06 12:43:05
【问题描述】:

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

特别是,为什么枚举成员是通过类名而不是枚举本身来访问的?鉴于enum 是容器/作用域,就像namespaceclass 一样,为什么当它是enum 时访问容器元素的处理方式与当它是class 时不同?

给定

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

        int myint;
    };
}

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

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

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

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

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

【问题讨论】:

  • 我认为这与 C 兼容性有关,但如果应该考虑使用添加到 C++11 中的 enum class,它们会遵守正确的语义`

标签: c++ enums rationale


【解决方案1】:

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

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

普通C++03enum:

enum Cpp03 { a, b, c };

C++11 基于enum

enum Cpp11Based: long { a, b, c };

C++11 scoped 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 提供范围功能。

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

【讨论】:

  • 你一针见血。我最初在 VC++ 中使用范围,但一直在以“正确”的方式做事,以避免警告我没有注意到它在 GCC(我目前正在使用)上的行为不同。
  • 请注意:正确的语法是 enum class EnumName : int 而不是 enum class : int EnumName
  • @MahmoudAl-Qudsi:谢谢!我将编辑答案(语法不正确)。我只是从头顶写下,我不认为我有一个接受这种语法的编译器,虽然我认为最新版本的 g++ 确实支持它,而且可能,clang 也支持它。
【解决方案2】:

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

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

与:

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

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

【讨论】:

  • 只是给读者的说明 -- @Jerry 我知道你知道这一点:一个区别是在 C++ 中,没有从例如的隐式转换。 int 到枚举值(但还有其他方式)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
  • 2011-06-17
  • 2014-12-19
  • 2014-11-27
  • 2015-08-18
相关资源
最近更新 更多