Обоснование семантики доступа enum в C++

Может кто-нибудь пролить свет на семантику для доступа к перечислению, определенному в классе в C++?

В частности, почему члены перечисления доступны по имени класса, а не по самому перечислению? Учитывая, что enum это контейнер / область, так же, как namespace а также class почему доступ к элементу контейнера обрабатывается по-разному, когда это enum чем когда это class?

Дано

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

        int myint;
    };
}

Почему полное название для enum1mynamespace::myclass::enum1 и не mynamespace::myclass::myenum::enum1?

Хотя последний "работает", это не "рекомендуемый" способ вызова, и некоторые компиляторы выдают там предупреждение. ИМХО, оно должно быть не только правильным, но и единственным способом доступа к нему.

Это делает для действительно странных правил доступа, и делает вещи очень странными, когда вы добавляете новый enum1 в другом перечислении (в этот момент вы должны добавить классификатор).

Действительно, это побеждает цель перечисления. Члены enum действительно больше членов класса, чем enum, и я должен сказать, что считаю поведение в других языках (например, C#) гораздо более предпочтительным.

Я предполагаю, что это для обеспечения совместимости с C, но я не понимаю, почему лучше было бы указывать имя enum в семантике доступа... Я думаю, что сделать имя класса необязательным было бы вариантом, сохраняющим совместимость с C,

2 ответа

Решение

В 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,

Я предполагаю, что то, с чем вы столкнулись, это расширение языка.

Основной ответ заключается в том, что ваш "Учитывая, что enum является контейнером / областью видимости "просто неправильно - согласно C и C++, enum не устанавливает область действия (и не является контейнером).

Короче, enum whatever { a, b, c};

не сильно отличается от:

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

Пока вы можете использовать enum whatever чтобы определить переменные, которые могут содержать значения этого типа, они, как правило, не сильно отличаются от некоторого целочисленного типа, способного содержать правильный диапазон значений.

Другие вопросы по тегам