How solve compiler enum redeclaration conflict
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;
}
Solution 2
Use scoped enum
s (C++ 11) - enum class
es. 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).
Related videos on Youtube
Comments
-
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
toUNKNOWN_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 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 likevoid foo(Identity::value)
, but you still lose the benefits of type safety, etc. -
EmDroid over 8 yearsWell, 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 :-)