Рассмотрим следующую декларацию перечисления:
enum Foo { Bar, Baz, Qux };
Теперь рассмотрим, я хочу, чтобы перечислители (Bar, Baz и Qux) имели определенные значения. Я могу решить это, просто инициализируя их в объявлении:
enum Foo { Bar = 4, Baz = 2, Qux = 42 };
А что если я не хочу, чтобы эти значения были известны? Например, при использовании других предопределенных значений из других библиотек или при использовании одного и того же значения для двух перечислителей. Примеры:
enum Foo { Bar = MY_LIB_BAR, Baz = MY_LIB_BAZ, Qux = MY_LIB_QUX };
enum Foo { Bar = 0, Baz = 42, Qux = 0 };
Я пробовал такие вещи:
// In header
enum Foo { Bar, Baz, Qux };
// In source
Foo { Bar = 0, Baz = 42, Qux = 0 };
// ...or...
Foo::Bar = 0, Foo::Baz = 42, Foo::Qux = 0;
Очевидно, ни одна из моих попыток не сработала.
Итак, мой вопрос заключается в следующем: есть ли способ инициализировать перечислители вне их декларации? Если да, то как это сделать, например, в соответствующем исходном файле .cpp?
РЕДАКТИРОВАТЬ Я могу указать базовый тип моего перечисления. Учитывая, что C ++ 11 допускает предварительное объявление, я подумал, что моя проблема может быть решена, поскольку перечисление становится полным типом.
Это невозможно. Причина проста, например, перечисления часто используются в switch
заявления. Для этих утверждений константы должны быть известны во время компиляции. Если вы можете опустить их в заголовке, то компилятор не сможет скомпилировать switch
в другом блоке осцилляции, так как он не будет иметь доступа к значениям.
То же самое касается всех constexpr
s: Они должны быть определены там, где они объявлены по одной и той же причине: компилятор всегда должен знать их значения.
Если вам действительно нужно спрятаться int
константы, затем просто определите их как обычные константы, например:
Foo.hpp:
class Foo {
static const int Bar;
static const int Baz;
static const int Qux;
}
foo.cpp:
const int Foo::Bar = 47;
const int Foo::Baz = 11;
const int Foo::Qux = 4711;
Конечно, вы теряете возможность использовать эти константы в switch
заявление!
Я могу указать основной тип моего перечисления. Учитывая, что
C ++ 11 допускает прямое объявление, я думал, что моя проблема может быть
решено, так как перечисление становится полным типом.
Это совсем не помогает! Прямое объявление констант enum просто невозможно, даже в C ++ 11 и C ++ 14.
Нет никакого способа — у перечислений всегда есть инициализаторы как часть объявления enum, и они не могут быть разделены на файл .cpp. То же самое с типизированными C ++ 11 перечислениями.
Перечисления являются постоянными значениями, которые оцениваются во время компиляции, поэтому вы можете разделить их на объявление и определение, как и многие другие типы. Объявление перечисления также должно быть его определением, поэтому оно должно быть полным со значениями и всем, когда вы объявляете это.
Тип перечисления является конечным набором проектным намерением.