2

誰かがC++のクラスで定義された列挙型にアクセスするためのセマンティクスに光を当てることができますか?

特に、列挙型メンバーが列挙型自体ではなくクラスの名前でアクセスされるのはなぜですか?がコンテナ/スコープであるとするとenum、同じように、コンテナの要素にアクセスするのは、それがであるときとそうでないときで異なる扱いを受けるのはなぜですか?namespaceclassenumclass

与えられた

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

        int myint;
    };
}

完全修飾名がenum1 mynamespace::myclass::enum1ではないのはなぜ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 };

C ++ 11ベースenum

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

C ++ 11スコープenum(例のように、名前のスコープとして機能します):

enum class Cpp11Scoped1 { a, b, c };
enum struct Cpp11Scoped2 { a, b, c };

最後の2つの形式は同等であり、たとえば、を書くことができCpp11Scoped1::aます。

最後に、スコープenumはベースにすることができます(名前の基になるタイプ、つまりサイズと符号を指定します)。

enum class Cpp11ScopedAndBased: long { a, b, c };

VisualC++を含む一部のC++03コンパイラは、通常のC++03にもスコープ機能を提供していましたenum

私の推測では、あなたが遭遇したのは言語拡張です。

于 2012-03-21T23:06:13.670 に答える
1

基本的な答えは、「enumコンテナ/スコープであるとすれば」はまったく間違っているということです。CおよびC ++によると、はスコープを確立enumしません(コンテナではありません)。

要するに、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 に答える