How to get enum from a different namespace.

Discussion in 'C++' started by toton, Sep 21, 2006.

  1. toton

    toton Guest

    Hi,
    I have some enum (enumeration ) defined in some namespace, not inside
    class. How to use the enum constant's in some other namespace without
    using the whole namespace.

    To say in little detail, the enum is declared as,
    namespace test{
    enum MyEnum{
    VALUE1,VALUE2
    };
    }
    now in another namespace,
    using test::MyEnum; //It gets myenum.

    MyEnum e = VALUE1; //It doesnt get the value.
    One solution is to have using test::VALUE1;
    but as such enum const's are huge in number it is not possible to use
    all of them seperately.
    Other way is to have using namespace test; But the namespace has many
    other things and I want to avoid such statement if possible.

    It looks the enum constants are 'free' inside the namespace, not
    guarded by the MyEnum.

    Anyway to deal with it? Is it possible to enclose them inside a dummy
    class and use them ?
     
    toton, Sep 21, 2006
    #1
    1. Advertising

  2. toton

    mlimber Guest

    toton wrote:
    > Hi,
    > I have some enum (enumeration ) defined in some namespace, not inside
    > class. How to use the enum constant's in some other namespace without
    > using the whole namespace.
    >
    > To say in little detail, the enum is declared as,
    > namespace test{
    > enum MyEnum{
    > VALUE1,VALUE2
    > };
    > }
    > now in another namespace,
    > using test::MyEnum; //It gets myenum.
    >
    > MyEnum e = VALUE1; //It doesnt get the value.
    > One solution is to have using test::VALUE1;
    > but as such enum const's are huge in number it is not possible to use
    > all of them seperately.
    > Other way is to have using namespace test; But the namespace has many
    > other things and I want to avoid such statement if possible.
    >
    > It looks the enum constants are 'free' inside the namespace, not
    > guarded by the MyEnum.
    >
    > Anyway to deal with it?


    You can explicitly qualify each constant:

    using test::MyEnum;
    MyEnum e = test::VALUE1;

    > Is it possible to enclose them inside a dummy class and use them ?


    I don't know quite what you mean, but I can still at least answer
    "probably not."

    Cheers! --M
     
    mlimber, Sep 21, 2006
    #2
    1. Advertising

  3. toton

    toton Guest

    mlimber wrote:
    > toton wrote:
    > > Hi,
    > > I have some enum (enumeration ) defined in some namespace, not inside
    > > class. How to use the enum constant's in some other namespace without
    > > using the whole namespace.
    > >
    > > To say in little detail, the enum is declared as,
    > > namespace test{
    > > enum MyEnum{
    > > VALUE1,VALUE2
    > > };
    > > }
    > > now in another namespace,
    > > using test::MyEnum; //It gets myenum.
    > >
    > > MyEnum e = VALUE1; //It doesnt get the value.
    > > One solution is to have using test::VALUE1;
    > > but as such enum const's are huge in number it is not possible to use
    > > all of them seperately.
    > > Other way is to have using namespace test; But the namespace has many
    > > other things and I want to avoid such statement if possible.
    > >
    > > It looks the enum constants are 'free' inside the namespace, not
    > > guarded by the MyEnum.
    > >
    > > Anyway to deal with it?

    >
    > You can explicitly qualify each constant:
    >
    > using test::MyEnum;
    > MyEnum e = test::VALUE1;
    >
    > > Is it possible to enclose them inside a dummy class and use them ?

    >
    > I don't know quite what you mean, but I can still at least answer
    > "probably not."

    Yes, but actually it is inside a nested namespace, and in actual case
    it looks like MyEnum e = com::ri::inkserver::server::ui::VALUE1 :( .
    Which I do not like very much. Changing the namespace is not in my
    hand, as those are not my code!
    The otherway I was mentioning looks like
    namespace test {
    class MyClass {
    public:
    enum MyEnum{
    VALUE1,VALUE2
    };
    };
    }

    using test::MyClass;
    MyClass::MyEnum e = MyClass::VALUE1;
    Looks shorter. Here MyClass do not have any other purpose rather than
    holding the 'free' enum constants (As class hides the member variables,
    it hides enum variables also. but C/C++ enum do not! Though Java/C#
    enum do that).
    Thus here when the class is 'used' it comes with all of its member
    variables (static & non static) and do not anyway need to name enum
    valuse by fully qualifying it.

    Any suggestion ?
    > Cheers! --M
     
    toton, Sep 21, 2006
    #3
  4. Hello,

    toton wrote:

    > I have some enum (enumeration ) defined in some namespace, not
    > inside
    > class. How to use the enum constant's in some other namespace without
    > using the whole namespace.
    >
    > To say in little detail, the enum is declared as,
    > namespace test{
    > enum MyEnum{
    > VALUE1,VALUE2
    > };
    > }
    > now in another namespace,
    > using test::MyEnum; //It gets myenum.
    >
    > MyEnum e = VALUE1; //It doesnt get the value.

    [...]
    > It looks the enum constants are 'free' inside the namespace, not
    > guarded by the MyEnum.


    The enum constants are put into the scope where the enum type is
    defined. That's inherited from C. And it is definitely the source of
    your problem chiseled into stone.

    >
    > Anyway to deal with it? Is it possible to enclose them inside a dummy
    > class and use them ?


    If you do not want all from test, then perhaps you could put just the
    enums into a subnamespace as a workaround.

    namespace test{
    namespace enums{
    enum MyEnum{
    VALUE1,VALUE2
    };
    }
    }

    using namespace test::enums;

    MyEnum e = VALUE1; //It does get the value.

    Other than that, you will have to qualify the constants.

    I don't think there is any will to change C++ in any way that somewhat
    hidden names are pulled in via using. When using is called with some
    item, not a namespace, then just that name is expected, not a bunch of
    names. If pulling the enum in via using pulled its constants in as
    well, then this cleanliness would be lost. Whatever, C++ has never
    been designed to save every bit of typing, so you will have to add more
    namespaces or qualify the names.

    Bernd Strieder
     
    Bernd Strieder, Sep 21, 2006
    #4
  5. toton

    mlimber Guest

    toton wrote:
    > mlimber wrote:
    > > toton wrote:
    > > > Hi,
    > > > I have some enum (enumeration ) defined in some namespace, not inside
    > > > class. How to use the enum constant's in some other namespace without
    > > > using the whole namespace.
    > > >
    > > > To say in little detail, the enum is declared as,
    > > > namespace test{
    > > > enum MyEnum{
    > > > VALUE1,VALUE2
    > > > };
    > > > }
    > > > now in another namespace,
    > > > using test::MyEnum; //It gets myenum.
    > > >
    > > > MyEnum e = VALUE1; //It doesnt get the value.
    > > > One solution is to have using test::VALUE1;
    > > > but as such enum const's are huge in number it is not possible to use
    > > > all of them seperately.
    > > > Other way is to have using namespace test; But the namespace has many
    > > > other things and I want to avoid such statement if possible.
    > > >
    > > > It looks the enum constants are 'free' inside the namespace, not
    > > > guarded by the MyEnum.
    > > >
    > > > Anyway to deal with it?

    > >
    > > You can explicitly qualify each constant:
    > >
    > > using test::MyEnum;
    > > MyEnum e = test::VALUE1;
    > >
    > > > Is it possible to enclose them inside a dummy class and use them ?

    > >
    > > I don't know quite what you mean, but I can still at least answer
    > > "probably not."

    > Yes, but actually it is inside a nested namespace, and in actual case
    > it looks like MyEnum e = com::ri::inkserver::server::ui::VALUE1 :( .
    > Which I do not like very much. Changing the namespace is not in my
    > hand, as those are not my code!


    Well you could pull only the members of the ui namespace into the
    current scope, but the only other way is to apply "using" to each of
    the enumeration constants individually. If you can't change the
    namespace, then I might speculate that it is not liable to change
    anyway, so duplicating the values would be a one-time cut-and-paste
    thing.

    You should feel fine about "using" an entire namespace in a .cpp file.
    If you're adverse to using a namespace because you're writing code in a
    header, you should probably move that code to a .cpp file anyway
    (unless it's template code on a platform lacking the export keyword).
    As Sutter and Alexandrescu say in _C++ Coding Standards_, item 59
    (italics in original): "You can and should use namespace using
    declarations and directives liberally /in your implementation files
    after #include directives/ and feel good about it. Despite repeated
    assertions to the contrary, namespace using declarations and directives
    are not evil and they do not defeat the purposes of namespaces. Rather,
    they are what make namespaces usable."

    > The otherway I was mentioning looks like
    > namespace test {
    > class MyClass {
    > public:
    > enum MyEnum{
    > VALUE1,VALUE2
    > };
    > };
    > }
    >
    > using test::MyClass;
    > MyClass::MyEnum e = MyClass::VALUE1;
    > Looks shorter. Here MyClass do not have any other purpose rather than
    > holding the 'free' enum constants (As class hides the member variables,
    > it hides enum variables also. but C/C++ enum do not! Though Java/C#
    > enum do that).
    > Thus here when the class is 'used' it comes with all of its member
    > variables (static & non static) and do not anyway need to name enum
    > valuse by fully qualifying it.


    This won't work (or at least is worse than the other options described
    above since you'll still have to duplicate all the names).

    Cheers! --M
     
    mlimber, Sep 21, 2006
    #5
  6. toton

    werasm Guest

    toton wrote:

    > The otherway I was mentioning looks like
    > namespace test {
    > class MyClass {
    > public:
    > enum MyEnum{
    > VALUE1,VALUE2
    > };
    > };
    > }
    >


    One way is to redefine enums applicable to the scope you are in. In
    general, I tend to wrap my enumerated types with classes regardless.
    This allows features like forward declaring enumerated types, etc. You
    don't need to give the enumeration a name (as far as I know).

    struct MyEnum{ enum{
    VALUE1,
    VALUE2 };
    };

    - Can now be forward declared to be used as arguments to member
    function calls.

    class MyEnum;
    class x_c{ ... void foo(const MyEnum& ) ... };

    - Can be qualified like:

    MyEnum::VALUE1 etc...

    > using test::MyClass;
    > MyClass::MyEnum e = MyClass::VALUE1;
    > Looks shorter. Here MyClass do not have any other purpose rather than
    > holding the 'free' enum constants (As class hides the member variables,
    > it hides enum variables also. but C/C++ enum do not! Though Java/C#
    > enum do that).
    > Thus here when the class is 'used' it comes with all of its member
    > variables (static & non static) and do not anyway need to name enum
    > valuse by fully qualifying it.
    >
    > Any suggestion ?
    > > Cheers! --M
     
    werasm, Sep 21, 2006
    #6
  7. toton

    mlimber Guest

    werasm wrote:
    > toton wrote:
    >
    > > The otherway I was mentioning looks like
    > > namespace test {
    > > class MyClass {
    > > public:
    > > enum MyEnum{
    > > VALUE1,VALUE2
    > > };
    > > };
    > > }
    > >

    >
    > One way is to redefine enums applicable to the scope you are in. In
    > general, I tend to wrap my enumerated types with classes regardless.
    > This allows features like forward declaring enumerated types, etc. You
    > don't need to give the enumeration a name (as far as I know).
    >
    > struct MyEnum{ enum{
    > VALUE1,
    > VALUE2 };
    > };
    >
    > - Can now be forward declared to be used as arguments to member
    > function calls.
    >
    > class MyEnum;
    > class x_c{ ... void foo(const MyEnum& ) ... };


    This is entirely unnecessary since you can forward-declare enums
    without the struct:

    enum MyEnum;
    void Foo( MyEnum );

    enum MyEnum { E1, E2 };

    void Foo( const MyEnum e )
    {
    cout << (e==E1 ? "One" : "Two") << endl;
    }

    > - Can be qualified like:
    >
    > MyEnum::VALUE1 etc...


    The disadvantage here compared to namespaces is that you *must* qualify
    them. There is no using "using" to get rid of "MyEnum".

    Cheers! --M
     
    mlimber, Sep 21, 2006
    #7
  8. toton

    Jens Theisen Guest

    "mlimber" <> writes:

    > > - Can now be forward declared to be used as arguments to member
    > > function calls.
    > >
    > > class MyEnum;
    > > class x_c{ ... void foo(const MyEnum& ) ... };


    That will just be an empty class with a nested enum definition and is
    not what you want.

    > This is entirely unnecessary since you can forward-declare enums
    > without the struct:


    Comeau and gcc disagree, so I guess it's nonstandard. What compiler do
    you use?

    I don't know of a way to practically forward declare an enum in a
    standard way or a feasible workaround. If someone does, I'd like to
    hear.

    On the other matter, wrapping it in a class is a good idea to provide
    a namespace for all the enumerators.

    An alternative is to wrap it in a namespace:

    namespace MyEnum
    {
    enum enum_t
    {
    eSome,
    eAnother
    }
    }

    which has the advantage of being able to bring in all the enumerators
    in by doing

    using namespace MyEnum;

    Regards,

    Jens
     
    Jens Theisen, Sep 21, 2006
    #8
  9. toton

    toton Guest

    mlimber wrote:
    > werasm wrote:
    > > toton wrote:
    > >
    > > > The otherway I was mentioning looks like
    > > > namespace test {
    > > > class MyClass {
    > > > public:
    > > > enum MyEnum{
    > > > VALUE1,VALUE2
    > > > };
    > > > };
    > > > }
    > > >

    > >
    > > One way is to redefine enums applicable to the scope you are in. In
    > > general, I tend to wrap my enumerated types with classes regardless.
    > > This allows features like forward declaring enumerated types, etc. You
    > > don't need to give the enumeration a name (as far as I know).
    > >
    > > struct MyEnum{ enum{
    > > VALUE1,
    > > VALUE2 };
    > > };
    > >
    > > - Can now be forward declared to be used as arguments to member
    > > function calls.
    > >
    > > class MyEnum;
    > > class x_c{ ... void foo(const MyEnum& ) ... };

    >
    > This is entirely unnecessary since you can forward-declare enums
    > without the struct:
    >
    > enum MyEnum;
    > void Foo( MyEnum );
    >
    > enum MyEnum { E1, E2 };
    >
    > void Foo( const MyEnum e )
    > {
    > cout << (e==E1 ? "One" : "Two") << endl;
    > }
    >
    > > - Can be qualified like:

    It doesn't work with gcc. I can not forward declare enum with gcc (4.2)
    in my linux or mingw build!. Even visual c++ doesn't allow it ( I
    hadn't checked 8.0 version though).
    Enum's are free makes a big problem occationally. For important enum, I
    usually do a typesafe enum (which is a class !) .
    But a lots of time, I need enum simply to define enum without safety.
    It is always better to have enum const within its enum scope. The
    solution by me or werasm looks as fine as free standing enum. I do not
    see any problem there. Many time I also use enum within a class to make
    them class member (const static ). They lacks typesafety but otherwise
    just ok.
    However it is always better to have using MyEnum; and MyEnum::One kind
    of thing!
    (Those libary do not use namespace or a different namespace for each
    enum still use the comvention like enum AlignmentType{ atLEFT, atRIGHT
    , atCENTER} ; etc.
    If the namespace can be opened in CPP file then that solution is also
    good. (I need them in CPP file only, most of the time).

    > > MyEnum::VALUE1 etc...

    >
    > The disadvantage here compared to namespaces is that you *must* qualify
    > them. There is no using "using" to get rid of "MyEnum".
    >

    Looks better. Most of the time I do not want to get rid of MyEnum. It
    is always a good idea to know which enum you are talking. Do you ever
    want to get rid of the class name to which it's member variable
    belongs? note, enum is not free standing const, it is more than that.
    It is the collection of values, which is more important. And it is
    important to know them by the collection itself, just like all other
    classes! (There are different classes of class, most language do not
    implement all, or some. Most signeficant classes of clas type are,
    struct (value type class) ,class (ref type class) , enum, collection
    (they are different in general, they holds other classes in different
    way than normal class do), iterator, static (which holds all static
    members, non creatable class), exception (which can be throwed, and
    they themselves dont throw on creation!, A big problem with c++
    exception, I think not having a language type of exception class, what
    will happen when if fails to create a exception class!) , interface
    (definition type) , abstract (partially implemented type) ,primitive.
    And all category van be of sealed ( final) , and virtual.
    Thanks for all of yours valuable time .
    abir
    > Cheers! --M
     
    toton, Sep 22, 2006
    #9
  10. toton

    werasm Guest

    mlimber wrote:

    > This is entirely unnecessary since you can forward-declare enums
    > without the struct:


    Not on my compiler/s. Could you quote the standard, perhaps. I actually
    think I've read something on this caveat before (not being able to
    forward declare enums). I think the book was Imperfect C++, Matthew
    Wilson. I'm not sure though.


    > The disadvantage here compared to namespaces is that you *must* qualify
    > them. There is no using "using" to get rid of "MyEnum".


    The advantage is that you can either typedef the class, or pull it into
    scope explicitly.

    namespace a{namespace b{ namespace c{ enum x{ value }; }}};

    namespace d{
    using a::b::c::value; //and all other values required.
    }

    ....compared to...

    namespace a{namespace b{ namespace c{
    struct x{ enum{value}; } }}};

    namespace d{
    using a::b::c::x;

    //now qualification by x only...
    x::value1; //x::value_n...

    }

    Regards,

    Werner
     
    werasm, Sep 22, 2006
    #10
  11. toton

    werasm Guest

    Jens Theisen wrote:
    > Comeau and gcc disagree, so I guess it's nonstandard. What compiler do
    > you use?


    I think so too.

    >
    > I don't know of a way to practically forward declare an enum in a
    > standard way or a feasible workaround. If someone does, I'd like to
    > hear.


    I don't think there is one. I don't know why, but think there may be
    good reason. Maybe some std guru can comment :). The fact that comeau
    does not compile it, makes me wonder. I know VCC does compile it, but I
    work on more than one compiler - 4 to be precise (5 comeau included).

    > An alternative is to wrap it in a namespace:


    The problem with wrapping in a namespace, is that each value that forms
    part of the enum must be explicitly qualified (I think).

    therefore...

    using MyEnum::enum_t;

    int x = static_cast<int>(eSome); //error, no type eSome
    // in scope, required to qualify with MyEnum...

    Regards,

    Werner
     
    werasm, Sep 22, 2006
    #11
  12. toton

    Jens Theisen Guest

    "werasm" <> writes:

    > The problem with wrapping in a namespace, is that each value that forms
    > part of the enum must be explicitly qualified (I think).
    >
    > therefore...
    >
    > using MyEnum::enum_t;
    >
    > int x = static_cast<int>(eSome); //error, no type eSome
    > // in scope, required to qualify with MyEnum...


    Not if you use a using directive:

    using namespace MyEnum;
    ^^

    Regards,

    Jens
     
    Jens Theisen, Sep 22, 2006
    #12
  13. toton

    werasm Guest

    Jens Theisen wrote:
    > "werasm" <> writes:


    > Not if you use a using directive:
    >
    > using namespace MyEnum;


    Yes, true. Unfortunately this is not a good idea in an .h file (for
    qualification in class definitions). In general, it is not common to
    use enum values in class definitions, though. If the need was required,
    using an anonymous enum with a class is quite handy.
    struct someS{
    typedef x::y::z enum_t enum_t;

    //now values qualified here by enum_t::value;
    };

    I have also found that the class name can form part of the actual enum
    name (nice feature for categorisation). This could be true for
    namespaces too, though.

    struct State
    {
    enum
    {
    Standby, Maintenance, Operational, Shutdown
    };
    };

    Now qualify like:

    State::Standby etc... The qualifier name conveys information about the
    category of the enumerated type. A feature we often use. The biggest
    reason for doing this though, is the fact that forward declaration of
    enums don't work. If that was not the case, I would probably consider
    using namespaces to scope my enums like you propose.

    Regards,

    Werner
     
    werasm, Sep 22, 2006
    #13
  14. toton

    mlimber Guest

    Jens Theisen wrote:
    > "mlimber" <> writes:
    > > This is entirely unnecessary since you can forward-declare enums
    > > without the struct:

    >
    > Comeau and gcc disagree, so I guess it's nonstandard. What compiler do
    > you use?


    How about that? Comeau and gcc do issue a warning, but VC++ 6, 7, 7.1,
    8, and (most surprisingly) EDG don't.

    > I don't know of a way to practically forward declare an enum in a
    > standard way or a feasible workaround. If someone does, I'd like to
    > hear.


    How about the technique presented here:
    http://www.ddj.com/dept/cpp/184403894

    Cheers! --M
     
    mlimber, Sep 22, 2006
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. -

    enum within an enum

    -, Jun 12, 2005, in forum: Java
    Replies:
    6
    Views:
    591
  2. Jerminia
    Replies:
    3
    Views:
    659
    Roedy Green
    Oct 7, 2005
  3. Ernst Murnleitner

    How to enum an enum?

    Ernst Murnleitner, Nov 12, 2003, in forum: C++
    Replies:
    5
    Views:
    507
    Rolf Magnus
    Nov 13, 2003
  4. mrhicks
    Replies:
    2
    Views:
    460
    Dave Thompson
    Jun 10, 2004
  5. toton
    Replies:
    3
    Views:
    436
    Ian Collins
    Aug 23, 2006
Loading...

Share This Page