Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A way to use all the unqualified names in a C++0x enum class?

The new C++ (C++0x or C++11) has an new kind of enum, an "enum class" where the names are scoped to the enum (among other things).

enum class E {
    VAL1, VAL2
};

void fun() {
    E e = E::VAL1;  // Qualified name
}

I'm wondering, however, if I can selectively use the unqualified name in a certain scope. Something like:

void fun() {
    using E::*;
    E e = VAL1;
    switch (e) {
        case VAL2: ...

I see I can write using E::VAL1 and get one value. But I don't want to do that for every value of a larger enum.

like image 990
Rob N Avatar asked Sep 17 '11 18:09

Rob N


People also ask

Can a class and enum have same name?

The enum value BAD resides in the general identifier scope, while the class type BAR resides in the class identifier scope. That is the reason why you are allowed to have both an enum value and a class with the same name: both names do not collide.

Does C have enum class?

In C programming, an enumeration type (also called enum) is a data type that consists of integral constants. To define enums, the enum keyword is used.

Can enums be unnamed?

They do create distinct new types. (However, the type of an unnamed enumeration does not have a name; its type can be accessed with the keyword decltype or deduced via type deduction.)


2 Answers

There is no way to do this in C++11. Just in case you are not aware of it - you get the E::Val1 notation even for an unscoped enumeration. For such an enumeration, you have Val1 accessible with and without the use of E::.

But you cannot take a scoped enumeration and selectively make all its enumerators visible in a given scope. It should also be noted that you can not write using E::Val1. The spec explicitly forbids this, your compiler just doesn't reject it yet.

like image 193
Johannes Schaub - litb Avatar answered Oct 01 '22 18:10

Johannes Schaub - litb


This is also something I happen to want, but haven't gotten around to trying to solve. Here's an untested solution. EDIT: I tried it out and it works great! This is my very first C++11 utility macro. Also I added a one-past-the-end enumerator to help extend it to "derived" enumerations.

#define IMPORTABLE_ENUM( TYPENAME, ... ) \
\
struct import_ ## TYPENAME { \
    enum TYPENAME { \
        __VA_ARGS__ \
    }; \
}; \
\
typedef import_ ## TYPENAME :: TYPENAME TYPENAME;

This cannot be imported into a block scope, but defines a base class import_duck to bring the enumerators into a class. Usage:

IMPORTABLE_ENUM ( duck, huey, dewey, louie )

duck d = duck::dewey; // can't use unscoped enumerators here

struct duck_madness : private import_duck { // but inside a derived class
    duck who_did_it() { return huey; } // qualification is unnecessary
}

And since there is only one enum type even among derived classes, no static_cast is ever required.

like image 42
Potatoswatter Avatar answered Sep 30 '22 18:09

Potatoswatter