问题
Can someone shed some light on the semantics for accessing an enum defined in a class in C++?
In particular, why are enum members accessed by the name of the class rather than the enum itself? Given that the enum
is the container/scope, just as namespace
and class
are, why is accessing an element of the container treated differently when it's an enum
than when it's a class
?
Given
namespace mynamespace
{
class myclass
{
public:
enum myenum
{
enum1,
enum2
};
int myint;
};
}
Why is the fully-qualified name for enum1
mynamespace::myclass::enum1
and not mynamespace::myclass::myenum::enum1
?
While the latter "works," it's not the "recommended" way of calling it and some compilers will throw a warning there. IMHO, it should not only be right, but it should also be the only way of accessing it.
It makes for really odd access rules, and makes things very weird when you add a new enum1
in a different enum (at which point you must add the qualifier).
Really, it defeats the purpose of an enum. The members of the enum are really more members of the class than they are of the enum, and I must say I find the behavior in other languages (e.g. C#) to be much more preferable.
I imagine this is to keep compatibility with C, but I don't see why requiring the enum name in the access semantic would be the better option... I'd imagine making the class name optional would be the option that preserves C compatibility.
回答1:
In C++03, as in C, an enum
does not introduce a new scope. The names defined go into the surrounding scope. Which might be a namespace, or a class.
C++11 added scoped enums and based enums.
Ordinary C++03 enum
:
enum Cpp03 { a, b, c };
C++11 based enum
:
enum Cpp11Based: long { a, b, c };
C++11 scoped enum
(which acts as a scope for the names, like in your example):
enum class Cpp11Scoped1 { a, b, c };
enum struct Cpp11Scoped2 { a, b, c };
The last two forms are equivalent, and allow writing e.g. Cpp11Scoped1::a
.
Finally, a scoped enum
can be based (specifying the underlying type for the names, i.e. size and signedness):
enum class Cpp11ScopedAndBased: long { a, b, c };
Some C++03 compilers, including Visual C++, provided the scope functionality also for the ordinary C++03 enum
.
My guess is that what you have run into, a language extension.
回答2:
The basic answer is that your "Given that the enum
is the container/scope" is just plain wrong -- according to C and C++, an enum
does not establish a scope (and is not a container).
In short, enum whatever { a, b, c};
isn't a whole lot different from:
const int a = 0;
const int b = 1;
const int c = 2;
While you can use enum whatever
to define variables able to hold the values of that type, they're not generally a whole lot different from some integer type capable of holding the right range of values.
来源:https://stackoverflow.com/questions/9814074/rationale-behind-enum-access-semantics-in-c