Reputation: 11108
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;
}
P.S. The question in code.
Update: Actually the bug is fixed in VS2010.
Upvotes: 3
Views: 414
Reputation: 47498
After adding the missing semicolon in B::E e3 = B::E::FIRST
, the following holds:
In C++03, only the first line (B::E e0 = A::FIRST;
) is correct, the other three are errors:
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
In C++0x, only the second line (B::E e2 = B::FIRST;
) is an error (FIRST is still not a member of B!), the other three are correct.
Not an answer to the "why?", just pointing out that there are two different issues at hand. The rationale for the issue that affects e1 and e3 is probably explained in the C++0x working papers.
The change was to the first sentence of 3.4.3[basic.lookup.qual]/1 which now says
The name of a class or namespace member or enumerator can be referred to after the :: scope resolution operator
But it used to say
The name of a class or namespace member can be referred to after the :: scope resolution operator
Upvotes: 5
Reputation: 131907
Enums only "overflow" in the surrounding namespace, aka the namespace of struct A
. A simple typedef won't yield the same effect for struct B
.
Also, if you enable warning level 4 (/W4), you'll get this nice warning:
warning C4482: nonstandard extension used: enum 'A::E' used in qualified name
It is not allowed to used A::E::XXX
to refer to the enum values in the current standard.
Upvotes: 2