Перечисление пересылки декларации и заголовочные файлы - PullRequest
0 голосов
/ 16 сентября 2018

В перечисленных типах LearnCPP CH4.5 указано

Поскольку компилятору необходимо знать, сколько памяти выделить для перечисления, вы не можете пересылать объявления типов перечисления. Тем не менее, есть простой обходной путь. Поскольку определение перечисления не выделяет никакой памяти, если перечисление требуется в нескольких файлах, можно определить перечисление в заголовке и #include этот заголовок, где это необходимо.

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

1 Ответ

0 голосов
/ 16 сентября 2018

Здесь утверждение на самом деле не о том, где объявлено перечисление, а о разнице между объявлением и определением.

Что-то вроде

enum MyEnum; // just a declaration, not a definition

struct Foo {
    MyEnum value;
};

не удается скомпилировать, потому что компилятор не может определить размер MyEnum только из объявления, но ему нужен этот размер для определения размера структуры Foo, определенной в приведенном выше фрагменте.

Это контрастирует с чем-то вроде

// the following is both a declaration and a defintion of the enum `MyEnum`
enum MyEnum {
    your,
    enumerators,
    go,
    here
};

struct Foo {
  MyEnum value;
};

, который компилируется, потому что компилятор теперь имеет всю необходимую информацию для определения размера структуры Foo.

Однако источник, который вы цитировали, кажется немного устаревшим. Начиная с C ++ 11 объявления перечисления может быть достаточно, пока известен его размер, т. Е. Потому что вы либо явно указываете базовый тип перечисления с незаданной областью (например, enum MyEnum : unsigned int;), либо потому, что вы используете перечисление с ограничением, которое по умолчанию использует int в качестве базового типа. Это

enum MyEnum : int; // declaration only, but with specified underlying type
enum class Bar;  // also only declaration, `int` is implicit underlying type

struct Foo {
    MyEnum v1;
    Bar v2;
};

компилируется просто отлично.

...