Enums in namespaces v/s classes in namespaces.

Enums in namespaces v/s classes in namespaces.

Post by S.K.Mod » Mon, 17 Jul 2000 04:00:00



Can anyone suggest a solution to the following problem:-

namespace XXXX {
      enum ErrorCode { e0, e1, e2, ... };
     ...

Quote:}

Suppose this has been used all over the place like:-
XXXX::e0, XXXX::e1 etc.

Now I need to convert uint's to ErrorCode's because
certain ranges of uint's map to certain ErrorCode's. So
I change the above to:-

class ErrorCode {
     ecode code;

public:
     enum ecode { e0, e1, e2, ... };
     ErrorCode(uint);
     operator uint() const;   ////do conversion here.

Quote:};

But now I have to write XXXX::ErrorCode::e0, XXXX::ErrorCode::e1, etc.
Is there any way to preserve the existing semantics?

Alternatively is there some way to provide a conversion from uint
to XXXX::ErrorCode?

Thanks.

Regards,
S. K. Mody.

 
 
 

Enums in namespaces v/s classes in namespaces.

Post by Rudolf Polze » Mon, 17 Jul 2000 04:00:00




Quote:> Can anyone suggest a solution to the following problem:-

> namespace XXXX {
>       enum ErrorCode { e0, e1, e2, ... };
>      ...
> }

> Suppose this has been used all over the place like:-
> XXXX::e0, XXXX::e1 etc.

> Now I need to convert uint's to ErrorCode's because
> certain ranges of uint's map to certain ErrorCode's. So
> I change the above to:-

> class ErrorCode {
>      ecode code;

> public:
>      enum ecode { e0, e1, e2, ... };
>      ErrorCode(uint);
>      operator uint() const;   ////do conversion here.
> };

> But now I have to write XXXX::ErrorCode::e0, XXXX::ErrorCode::e1, etc.
> Is there any way to preserve the existing semantics?

> Alternatively is there some way to provide a conversion from uint
> to XXXX::ErrorCode?

> Thanks.

> Regards,
> S. K. Mody.

Sorry, I do not see your problem.
Why are you declaring the enum in the class definition and not outside?
If you declare it outside, there will be no problem.

enum { e0, e1, e2, ... }; // an anonymous enumeration
class ErrorCode {
     unsigned int code;

public:
     ErrorCode (unsigned int);
     operator unsigned int() const;   ////do conversion here.

Quote:};

But there IS a problem with this: If you write:
e0 + 1
the compiler does not know which conversions to do:
uint(e0) + 1
or
e0 + ErrorCode (1).

This is only a problem if you define operator+() for ErrorCode, but it
shows there ARE problems.

There is no real workaround for this, but the following code will work
now:

try
{
 throw e0;

Quote:}

catch (ErrorCode e)
{
 // ...

Quote:}

This works, but if you throw an unsigned int, the error handler also
gets the exception.

There is only one good way, which unfortunately doesn't preserve the
old semantics:

enum { e0, e1, e2, ... }; // an anonymous enumeration
class ErrorCode {
     unsigned int code;
public:
     explicit ErrorCode (unsigned int);
     int toInt() const;   ////do conversion here.

Quote:};

But then you have to change all your code, which you have noticed, but
else the ErrorCode class is not type-safe and can cause ambiguities.

Perhaps this could be possible:

class ErrorCode {
     unsigned int code;
public:
     explicit ErrorCode (unsigned int);
     int toInt() const;   ////do conversion here.

Quote:};

const ErrorCode e0 (0);
const ErrorCode e1 (1); // ...

This preserves the old semantics in throwing the errors, but not in
comparing.

But you cannot have the comfort of the enumeration now, but if you need
short code, MM works (macro magic). But if you are using namespaces, I
think that you do not want to use dirty global macros in it.

--
Rudolf Polzer

Sent via Deja.com http://www.deja.com/
Before you buy.

 
 
 

Enums in namespaces v/s classes in namespaces.

Post by S.K.Mod » Mon, 17 Jul 2000 04:00:00





>namespace XXXX {
>       enum ErrorCode { e0, e1, e2, ... };
>      ...
> }

[cut]

Quote:> > Now I need to convert uint's to ErrorCode's because
> > certain ranges of uint's map to certain ErrorCode's. So
> > I change the above to:-

> > class ErrorCode {

[cut]

Quote:> Why are you declaring the enum in the class definition and not outside?
> If you declare it outside, there will be no problem.

I usually declare enums in classes or namespaces. Often the
enum constants have the same (or similar) names. Alternatively
I could prefix each enum name with the class or namespace
name like:-
    XXXX_e0;
but its not as clean.

Quote:> enum { e0, e1, e2, ... }; // an anonymous enumeration
> class ErrorCode {
>      unsigned int code;

> public:
>      ErrorCode (unsigned int);
>      operator unsigned int() const;   ////do conversion here.
> };

> But there IS a problem with this: If you write:
> e0 + 1
> the compiler does not know which conversions to do:
> uint(e0) + 1
> or
> e0 + ErrorCode (1).

> This is only a problem if you define operator+() for ErrorCode, but it
> shows there ARE problems.

If operator+() is defined as a member function:-
       ErrorCode ErrorCode::operator+(unsigned int) {...}

then there is no problem(?). However, I probably don't need
operator+() in this particular case.

Quote:> There is no real workaround for this, but the following code will work
> now:

> try
> {
>  throw e0;
> }
> catch (ErrorCode e)
> {
>  // ...
> }

> This works, but if you throw an unsigned int, the error handler also
> gets the exception.

I believe try - catch pairs require the _exact_ type to match. ie:-
     try { throw 1; }
     catch (ErrorCode e) {;}

will not work even if there is an implicit conversion from
unsigned int to ErrorCode, so this is not a problem. My intention
is to use the throw statement like:-
    throw ((ErrorCode)n);  ////n is unsigned int.

- Show quoted text -

Quote:

> There is only one good way, which unfortunately doesn't preserve the
> old semantics:

> enum { e0, e1, e2, ... }; // an anonymous enumeration
> class ErrorCode {
>      unsigned int code;
> public:
>      explicit ErrorCode (unsigned int);
>      int toInt() const;   ////do conversion here.
> };

> But then you have to change all your code, which you have noticed, but
> else the ErrorCode class is not type-safe and can cause ambiguities.

> Perhaps this could be possible:

> class ErrorCode {
>      unsigned int code;
> public:
>      explicit ErrorCode (unsigned int);
>      int toInt() const;   ////do conversion here.
> };
> const ErrorCode e0 (0);
> const ErrorCode e1 (1); // ...

Ah yes, thanks! I think this should work for me, but why toInt()?
I would just use operator unsigned int(). If there is any special
addition or comparison to be done, I would use member
functions:-
     bool ErrorCode::operator<(ErrorCode) {... }
     ErrorCode ErrorCode::operator+(unsigned int) {...}
   etc...

Making the constructor explicit is good idea also. Thanks.

Quote:> This preserves the old semantics in throwing the errors, but not in
> comparing.

> But you cannot have the comfort of the enumeration now, but if you need
> short code, MM works (macro magic). But if you are using namespaces, I
> think that you do not want to use dirty global macros in it.

> --
> Rudolf Polzer

Regards,
S. K. Mody.
 
 
 

1. Global namespace vs. base class namespace

Consider this code sample.

void f(){};
class A
{
public:
  virtual void f(){}
class B : public A
{
public:
  virtual void f(){ /* ??? */ }

int main()
{
 B b;
 b.f();
 return 0;

Replace ??? with f().  That is recursive as B::f is called.
Replace ??? with A::f().  A::f is called.
Replace ??? with ::f().  The global function f is called.

Let's assume that we actually want A::f.  At a later date, class C is
inserted in the hierarchy, i.e.
class A
class C : public A
class B : public C

Now we want B::f to call C::f, but we have to change the code.  What we
really wanted all along is for B::f to simply call "my base class
version", whichever that might be.  If ::f referred to "a namespace one
level up", it would work, but it really refers explicitly to the global
namespace (I think).  Is there a way *built in* to the language to call
a base class version of your function without explicitly naming the
base class?

--
Regards,
Jeff

Sent via Deja.com http://www.deja.com/
Before you buy.

2. proc mixed

3. Shell Namespace : How to create a namespace like "My Computer"

4. Sugestions for Xbox-2!!!

5. Root shell namespace and Nonroot namespace.

6. Removing Program from Taskbar at *Runtime*

7. Namespaces: IE4's Address Bar blank for my namespace.

8. Is this a limitation of the FP editor? I'm frustrated!

9. Namespace Maintenance, Parent Namespace?

10. namespaces in XML and namespaces in C++

11. namespace aliases and extension-namespace-definition

12. namespace and enums, how?

13. help: enum's and namespaces (subclasses)