Проблема с определением типов.И ошибка в визуальной студии 2005 - PullRequest
3 голосов
/ 17 мая 2011
struct A
{
    enum E
    {
        FIRST,
        SECOND
    };
};

struct B
{
    typedef A::E E;
};

int main()
{
    B::E e0 = A::FIRST;//OK (this case is clear for me)
    B::E e1 = A::E::FIRST;//OK (this case is clear for me as well)
    B::E e2 = B::FIRST;//Compile Error: FIRST is not member of B (Why isn't this allowed? Don't we lose meaning of typedef of enums in this case?)
    B::E e3 = B::E::FIRST;//Error of compiler (If there were no bug in visual studio 2005 compiler, would this code work?)
    return 0;
}

PS Вопрос в коде.

Обновление: На самом деле ошибка исправлена ​​в VS2010.

Ответы [ 2 ]

5 голосов
/ 19 мая 2011

После добавления пропущенной точки с запятой в B::E e3 = B::E::FIRST выполняется следующее:

В C ++ 03 верна только первая строка (B::E e0 = A::FIRST;), остальные три ошибки:

B::E e1 = A::E::FIRST; // error: ‘A::E’ is not a class or namespace
B::E e2 = B::FIRST; // error: ‘FIRST’ is not a member of ‘B’
B::E e3 = B::E::FIRST; // error: ‘B::E’ is not a class or namespace

В C ++ 0x только вторая строка (B::E e2 = B::FIRST;) является ошибкой (FIRST по-прежнему не является членом B!), Остальные три верны.

Не ответ на вопрос «почему?», Просто указывает на то, что есть две разные проблемы под рукой. Обоснование проблемы, которая затрагивает e1 и e3, вероятно, объясняется в рабочих документах C ++ 0x.

Изменение было в первом предложении 3.4.3 [basic.lookup.qual] / 1 , которое теперь говорит

На имя члена класса, пространства имен или перечислителя можно ссылаться после оператора разрешения области действия

Но раньше говорилось

На имя члена класса или пространства имен можно ссылаться после оператора :: scope resolution

2 голосов
/ 17 мая 2011

Перечисляет только «переполнение» в , окружающем пространство имен , то есть пространство имен struct A.Простой typedef не даст такой же эффект для struct B.


Также, если вы включите предупреждение уровня 4 (/ W4), вы получите это приятное предупреждение:

предупреждение C4482: использовано нестандартное расширение: enum 'A :: E' используется в квалифицированном имени

Нельзя использовать A::E::XXX для ссылки на значения перечисления в текущем стандарте.

...