Можно ли отделить значения enum от декларации?

0

У меня есть.h файл:

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

Можно ли отделить "= значение" от этого объявления до другого места, а именно связанного файла cpp? Причина в том, что это перечисление имеет странные значения, предоставляемые удаленным сервером, который я не контролирую. Я хотел бы удалить его из глаз клиента.

Я хотел бы иметь.cpp файл с

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

Но компилятор говорит, что я переопределяю MyTypes, что верно.

  • 0
    зачем помещать его в файл .cpp, чтобы решить проблему с удаленного сервера?
Теги:
enums

3 ответа

4

Для подтверждения Криса комментария c++ 11 позволяет переадресовать объявить перечисления. Следующий код не будет выполнен в c++ 03, но скомпилирован в c++ 11:

struct S {
    enum E : int;  
};

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

N2764, а также Forward, объявляющие перечисление в c++, более подробно, но:

Причина, по которой перечисление не может быть объявлено вперед, заключается в том, что, не зная значений, компилятор не может знать хранилище, необходимое для переменной enum.

Это необязательно для enum class поскольку по умолчанию используется тип int.


"Обходной путь" - это переслать декларацию структуры, содержащей перечисление. Кредит идет к Лешеку Свирски. Примечание: переменные макросы являются расширением gcc в 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);
  • 0
    Спасибо за разъяснения. Однако я не могу использовать C ++ 11 из-за ограничений платформы.
  • 0
    @ Эрик, я сделал правку.
3

Я не думаю, что это возможно с помощью enum. Я могу думать о нескольких возможных решениях:

  1. Используйте глобальные статические переменные. Это означает, что вам нужно только объявить переменные в файле.h, и вы можете определить и инициализировать их в файле.cpp.

  2. Создайте класс с методами getter, которые возвращают значения.

  3. Создайте один метод getter, который возвращает "реальные" значения на основе "фиктивного" перечисления.

1

Вы можете переслать объявление enum:

class MyClass
{
    enum MyTypes;
};

с последующим

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

Никто, кроме вашего класса, не сможет использовать эти имена, потому что они еще не определены; учитывая, что enum в любом случае является private в этом примере, это должно быть хорошо.

  • 1
    Не уверен насчет внутренних классов, но вне классов вам нужно будет указать базовый тип. Изменить: Да, попробуйте удалить базовый тип отсюда .
  • 0
    Некоторое Обоснование @ Крис может быть найдено в этом ответе здесь . Кажется, вы уже знаете об этом, если исходить из вашего примера.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню