How solve compiler enum redeclaration conflict

12,618

Solution 1

You can use scoped enumerations for this. This requires C++11 or higher support.

enum class Identity
{
       UNKNOWN = 1,
       CHECKED = 2,
       UNCHECKED =3
};

enum class Status
{
       UNKNOWN = 0,
       PENDING = 1,
       APPROVED = 2,
       UNAPPROVED =3
};

int main ()
{
    Identity::UNKNOWN;
    Status::UNKNOW;
}

Live Example

Solution 2

Use scoped enums (C++ 11) - enum classes. They will not pollute the outer scope with duplicate names.

But, you'll need to access the enumerated values with a scope resolution operator - Identity::UNKNOWN, which is not a bad thing.

Solution 3

If using C++11 is not feasible(It really should by now, I mean, it's already 2015), consider using namespaces:

namespace Identity {
enum {
       UNKNOWN = 1,
       CHECKED = 2,
       UNCHECKED =3
};
}

namespace Status {
enum {
       UNKNOWN = 0,
       PENDING = 1,
       APPROVED = 2,
       UNAPPROVED =3
};
}

But, really, enum class is much better.

Solution 4

This is how I would usually declare such enums (if I don't need something more fancy, like automatic conversions of the enum names to strings, serialization/deserialization etc.):

struct Identities
{
    enum Type
    {
        UNKNOWN   = 1,
        CHECKED   = 2,
        UNCHECKED = 3
    };
};

typedef Identities::Type Identity;

struct States
{
    enum Type
    {
        UNKNOWN    = 0,
        PENDING    = 1,
        APPROVED   = 2,
        UNAPPROVED = 3
    };
};

typedef States::Type Status;

// usage
Identity identity = Identities::UNKNOWN;
Status status = States::UNKNOWN;

Works in every C++ version and is type safe as well. Namespaces can be also used instead of structs (but I normally use structs).

Share:
12,618

Related videos on Youtube

Daniel Santos
Author by

Daniel Santos

Professional and hobbist developer.

Updated on July 12, 2022

Comments

  • Daniel Santos
    Daniel Santos almost 2 years

    Consider the following C++ enumerations:

    enum Identity
    {
        UNKNOWN   = 1,
        CHECKED   = 2,
        UNCHECKED = 3
    };
    
    enum Status
    {
        UNKNOWN    = 0,
        PENDING    = 1,
        APPROVED   = 2,
        UNAPPROVED = 3
    };
    

    The Compiler conflicted the both UNKNOWN items and threw this error:

    error: redeclaration of 'UNKNOWN'

    I am able to solve this error changing one of the UNKNOWN to UNKNOWN_a, but I would like to do not change the names.

    How can I solve this conflict without changing the enum items name?

  • Cássio Renan
    Cássio Renan over 8 years
    @chris I'm aware. This is one of the problems of not simply using enum class. I mean, you could still just declare the enums with a name (enum value { /*...*/) and use them like void foo(Identity::value), but you still lose the benefits of type safety, etc.
  • EmDroid
    EmDroid over 8 years
    Well, the funny thing is that C++11 is quite commonly not feasible especially in the commercial area - for example, many customers of the company I work for are still using old systems like RHEL and don't want to upgrade as long as the system runs well (it is pretty common to hit serious incompatibilities during release upgrade). So as the result, C++11 is banned and everything must build in older compilers as well. In the fact, C++11 was banned in every of the last 4 companies I worked for. And one company I previously worked for is AFAIK still building in MSVC 6 too :-)