0

I have a .h file :

class MyClass
{
  enum MyTypes{
     type1 = 1,
     type2 = 2,
     type3 = 3,
     // and so on
  };
};

Is it possible to separate the " = value " from this declaration to another location, namely the related cpp file? The reason is that this enumeration has weird values provided by a remote server that I do not control. I would like to remove it from client's eyes.

I'd like to have a .cpp file with

enum MyClass::MyTypes{
  type1 = 12,
  type2 = 14,
  type3 = 28,
  // and so on
};

But the compiler says that I redefine MyTypes, which is true.

Eric
  • 19,525
  • 19
  • 84
  • 147

3 Answers3

4

To corroborate chris's comment, C++11 allows you to forward declare enums. The following code will fail in C++03 but compile in C++11:

struct S {
    enum E : int;  
};

enum S::E : int {
    a,b,c
};

N2764 as well as Forward declaring an enum in c++ go into more detail, but:

The reason the enum can't be forward declared is that without knowing the values, the compiler can't know the storage required for the enum variable.

This is not necessary for an enum class because the default type is int.


A "workaround" is to forward declare a struct containing an enum. Credit goes to Leszek Swirski. Note: variadic macros are a gcc extension in C++03.

#define ENUM_CLASS(NAME, TYPE, VALUES...) \
struct NAME { \
  enum e { VALUES }; \
  explicit NAME(TYPE v) : val(v) {} \
  NAME(e v) : val(v) {} \
  operator e() const { return e(val); } \
  private:\
  TYPE val; \
}

struct Enum;

void f(Enum e);

ENUM_CLASS(Enum, int,
 VALUE,
 ANOTHER_VALUE
);

void f (Enum e)
{
 switch(e)
 {
  case Enum::VALUE:
    std::cout << "VALUE" << std::endl;
    return;
  case Enum::ANOTHER_VALUE:
    std::cout << "ANOTHER_VALUE" << std::endl;
    return;
 }
}

f(Enum::ANOTHER_VALUE);
Community
  • 1
  • 1
  • Thanks for the clarification. However I cannot use C++11 due to platform restrictions. – Eric Jan 30 '14 at 06:15
3

I don't think this is possible using enum. I can think of several possible solutions:

  1. Use global static variables. This means you only need to declare the variables in the .h file and you can define and initialize them in a .cpp file.

  2. Create a class with getter methods that return the values.

  3. Create a single getter method that returns the "real" values based on a "dummy" enum.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
1

You can forward declare the enum:

class MyClass
{
    enum MyTypes;
};

followed by

enum MyClass::MyTypes
{
    type1 = 12, // ...
};

No one but your class will be able to use these names because they are not yet defined; given that the enum is private in the example anyway, that should be fine.

Simon Richter
  • 28,572
  • 1
  • 42
  • 64
  • 1
    Not sure about inside classes, but outside of classes, you'd need to specify the underlying type. Edit: Yeah, try removing the underlying type from [here](http://coliru.stacked-crooked.com/a/98b3676b2f16ed1f). – chris Jan 30 '14 at 06:02
  • @chris Some rationale might be found in this answer [here](http://stackoverflow.com/a/72599/1508519). It seems you already know about that though, given from your example. –  Jan 30 '14 at 06:08
  • But then the users including the h file containing MyClass won't know about the enumeration. It defeats what I try to accomplish here – Eric Jan 30 '14 at 06:12
  • @remyabel, Come to think of it, I think I learnt it from [Wikipedia](http://en.wikipedia.org/wiki/C%2B%2B11#Strongly_typed_enumerations) of all things. I have to say the list of changes there is (or was when I was looking for something like that) pretty useful. – chris Jan 30 '14 at 06:13