2

I have several enum that has the same field names:

enum Response
{
  Ok = 0, 
  Busy = 1
}

enum Status
{
  Ok = 0, 
  LoggedOut = 1
}

This gives the error:

error: redeclaration of 'Ok'

How do to solve this problem?

UPD

Trying to use enum class:

enum class Response
{
  Ok = 0, 
  Busy = 1
}
Status s1 = Status::Ok ;

Got error:

Error: 'Status' is not a class or namespace
     Status s1 = Status::Ok ;
                 ^
vico
  • 17,051
  • 45
  • 159
  • 315
  • 4
    Use a namespace around the enums or newer C++11 enums (enum class). :) – xander Apr 19 '18 at 12:51
  • please dont edit the question according to answers you get. Imho before the question was ok (even as a dupe), but with that UDP (what is that supposed to mean anyhow?) it is rather confusing and the answers dont match your question anymore – 463035818_is_not_an_ai Apr 19 '18 at 13:57

3 Answers3

10

I would switch to using enum class

enum class Response
{
  Ok = 0, 
  Busy = 1
};

enum class Status
{
  Ok = 0, 
  LoggedOut = 1
};

then you can refer to an enum value without ambiguity

Status s = Status::Ok;
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • 2
    The second benefit here is that they are proper types, so if you have `Foo(Response e)`, in OP's example you could pass any `enum` or `int` there, whereas with `enum class` you can't – Tas Apr 19 '18 at 12:56
  • Got error `'Status' is not a class or namespace Status s = Status::Ok ; ^` – vico Apr 19 '18 at 13:18
  • Got error `Status is not a class or namespace` More details in UPD in question body – vico Apr 19 '18 at 13:24
  • 1
    @vico Works here: http://coliru.stacked-crooked.com/a/3d479628629d5bdf – NathanOliver Apr 19 '18 at 13:35
3

Another solution I was using pre-C++11:

struct Responses
{
  enum type {
    Ok = 0,
    Busy = 1
  };
};

typedef Responses::type Response;

struct States
{
  enum type {
    Ok = 0, 
    LoggedOut = 1
  };
};

typedef States::type Status;

Then referring to the enums as:

Response r1 = Responses::Ok;
Response r1 = Responses::Busy;
Status s1 = States::Ok;
Status s2 = States::LoggedOut;
EmDroid
  • 5,918
  • 18
  • 18
  • Why make an entire `struct` when a `namespace` would suffice? – Cory Kramer Apr 19 '18 at 13:04
  • True, namespace would basically work the same ... although the struct prevents doing `using namespace Responses; using namespace States;` and have the conflict back again. – EmDroid Apr 19 '18 at 13:07
  • This does solve the naming conflict (I use this also), but it still has the pitfall of you can pass `States::Ok` to a function expecting a `Responses`, so if one has C++11 they should definitely prefer `enum class` – Tas Apr 19 '18 at 22:34
  • just want to jot this down: I like this syntax a lot, and often I get carried away thinking it will translate clearly to C - but it does not, https://stackoverflow.com/a/48231009/6197439 explains nicely why – sdbbs Dec 21 '22 at 01:41
1

The problem is occurring because enum in C++ does not define a namespace, but rather a constant that can be implicitly converted to an int. Thus your code is similar to writing:

int Ok = 0;
int Busy = 1;

int Ok = 0;
int LoggedOut = 1;

Which, of course, produces a conflict. There are three possible approaches you can take to solve this, of which the first is the most desirable but the others are possible alternatives if you cannot use it for some reason:

(1) If you can use features from C++ 11 - which you should be able to - you can replace the enum with the newer enum class. Which both defines a separate namespace and is strongly typed, stopping you from mixing different enums together (see this question for more). e.g.

enum class Response
{
    Ok = 0, 
    Busy = 1
};

enum class Status
{
    Ok = 0, 
    LoggedOut = 1
};

You will now need to refer to this values in a scoped fashion, e.g. Status::Ok or Response::Busy.

(2) You can change the names to include the enum name:

enum Response
{
    Response_Ok = 0, 
    Response_Busy = 1
};

(3) You can encase the enums themselves in a namespace:

 namespace Status
 {
     enum Status
     {
         Ok = 0,
         LoggedOut = 1
     };
 }
Jack Aidley
  • 19,439
  • 7
  • 43
  • 70