How to get enum from a different namespace.

T

toton

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 ?
 
M

mlimber

toton said:
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
 
T

toton

mlimber said:
You can explicitly qualify each constant:

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


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 ?
 
B

Bernd Strieder

Hello,
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
 
M

mlimber

toton said:
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
 
W

werasm

toton said:
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...
 
M

mlimber

werasm said:
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
 
J

Jens Theisen

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
 
T

toton

mlimber said:
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;
}
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).
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
 
W

werasm

mlimber said:
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
 
W

werasm

Jens said:
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
 
J

Jens Theisen

werasm said:
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
 
W

werasm

Jens said:
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
 
M

mlimber

Jens said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top