304 votes

Forward déclarant une énumération en c ++

Je suis en train de faire quelque chose comme ce qui suit:

enum E;

void Foo(E e);

enum E {A, B, C};

le compilateur refuse. J'ai eu un coup d'oeil rapide sur Google et le consensus semble être que vous ne pouvez pas le faire", mais je ne comprends pas pourquoi. Quelqu'un peut-il m'expliquer? Merci beaucoup.

Clarification 2: je fais ce que je l'ai privé de méthodes dans une classe qui prennent en dit enum, et je ne veux pas l'énumération de valeurs exposées - ainsi, par exemple, je ne veux pas que quiconque de savoir que E est défini comme

enum E {
    FUNCTIONALITY_NORMAL, FUNCTIONALITY_RESTRICTED, FUNCTIONALITY_FOR_PROJECT_X
}

en tant que projet X n'est pas quelque chose que je veux que mes utilisateurs à connaître.

J'ai donc voulu déclarer avant la enum afin que je puisse mettre les méthodes privées dans le fichier d'en-tête, déclarer l'enum en interne dans le rpc, et distribuer la bibliothèque de fichiers d'en-tête et de personnes.

Comme pour le compilateur, c'est GCC.

264voto

user119017 Points 751

La déclaration forward d'enums est également possible en C ++ 0x. Auparavant, la raison pour laquelle les types enum ne pouvaient pas être déclarés en avant est parce que la taille de l'énumération dépend de son contenu. Tant que la taille de l'énumération est spécifiée par l'application, elle peut être déclarée en avant:

 enum Enum1;                   //Illegal in C++ and C++0x; no size is explicitly specified.
enum Enum2 : unsigned int;    //Legal in C++0x.
enum class Enum3;             //Legal in C++0x, because enum class declarations have a default type of "int".
enum class Enum4: unsigned int; //Legal C++0x.
enum Enum2 : unsigned short;  //Illegal in C++0x, because Enum2 was previously declared with a different type.
 

Pas vraiment ajouter quelque chose de nouveau, juste que c'est possible dans 0x.

230voto

KJAWolf Points 1570

La raison de l'enum ne pouvez pas être en avant de déclarer que, sans le savoir, les valeurs, le compilateur ne peut pas savoir à l'espace de stockage requis pour les enum variable. Compilateur C++ sont autorisés à spécifier le réel espace de stockage en fonction de la taille nécessaire pour contenir toutes les valeurs spécifiées. Si tout ce qui est visible est la déclaration anticipée, l'unité de traduction ne peut pas savoir quelle taille de stockage aura été choisi - c'est peut-être un char ou int, ou quelque chose d'autre.


À partir de la Section 7.2.5 du Standard ISO C++:

Le type sous-jacent d'une énumération est un type intégral qui peut représenter toutes les énumérateur des valeurs définies dans l'énumération. Elle est mise en œuvre défini le type intégral est utilisé comme le type sous-jacent pour une énumération, sauf que le type sous-jacent ne doit pas être plus grand que int moins que la valeur d'un agent recenseur ne peut pas s'insérer dans un int ou unsigned int. Si l' agent recenseur, la liste est vide, le type sous-jacent est comme si l'énumération n'avaient qu'un seul agent recenseur avec la valeur 0. La valeur de sizeof() appliqué à un type d'énumération, un objet de type énumération, ou un agent recenseur, est la valeur de sizeof() appliqué pour le type sous-jacent.

Depuis l' appelant de la fonction doit connaître les tailles des paramètres correctement l'installation de la pile d'appel, le nombre d'énumérations dans une énumération de la liste doit être connue avant le prototype de fonction.

Mise à jour: Dans C++0X une syntaxe pour l'avant-propos de déclarer les types enum a été proposé et accepté. Vous pouvez voir la proposition à l' http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf

95voto

Tom Points 780

Je suis en ajoutant une date de réponse ici, compte tenu des développements récents.

Vous pouvez l'avant-déclarer un enum en C++11, aussi longtemps que vous déclarer son type de stockage dans le même temps. La syntaxe ressemble à ceci:

enum E : short;
void foo(E e);

....

enum E : short
{
    VALUE_1,
    VALUE_2,
    ....
}

En fait, si la fonction ne renvoie jamais les valeurs de l'énumération, vous n'avez pas besoin de la déclaration complète à tous à ce point.

C'est pris en charge par G++ 4.6 et plus (-std=c++0x ou -std=c++11 dans les versions plus récentes). Visual C++ 2013 prend en charge ce; dans les versions antérieures, il a une sorte de non-support de la norme que je n'ai pas encore appris - j'ai trouvé quelques suggestion qu'une simple déclaration anticipée est légal, mais YMMV.

31voto

Brian R. Bondy Points 141769

Avant de déclarer les choses en C++ est très utile, car elle accélère considérablement le temps de compilation. Vous pouvez déclarer avant plusieurs choses en C++ dont: struct, class, function, etc...

Mais pouvez-vous déclarer avant l' enum en C++?

Non, vous ne pouvez pas.

Mais pourquoi ne pas l'autoriser? S'il lui est permis, vous pouvez définir votre enum type dans votre fichier d'en-tête, et votre enum valeurs dans votre fichier source. Sonne comme il devrait être autorisée à droite?

Mal.

En C++ il n'y a pas de type par défaut pour enum comme il est en C# (int). En C++, votre enum type sera déterminé par le compilateur pour être n'importe quel type qui s'adapte à la gamme de valeurs que vous avez pour votre enum.

Qu'est-ce que cela signifie?

Cela signifie que votre enum's sous-jacents ne peuvent pas être entièrement déterminé jusqu'à ce que vous avez toutes les valeurs de l' enum défini. Qui mans vous ne pouvez pas séparer la déclaration et la définition de votre enum. Et, par conséquent, vous ne pouvez pas déclarer avant l' enum en C++.

Le standard ISO C++ S7.2.5:

Le type sous-jacent d'une énumération est un type intégral qui peut représenter toutes les énumérateur des valeurs définies dans l'énumération. Elle est mise en œuvre défini le type intégral est utilisé comme le type sous-jacent pour une énumération, sauf que le type sous-jacent ne doit pas être plus grand que int moins que la valeur d'un agent recenseur ne peut pas s'insérer dans un int ou unsigned int. Si l'agent recenseur, la liste est vide, le type sous-jacent est comme si l'énumération n'avaient qu'un seul agent recenseur avec la valeur 0. La valeur de sizeof() appliqué à un type d'énumération, un objet de type énumération, ou un agent recenseur, est la valeur de sizeof() appliqué pour le type sous-jacent.

Vous pouvez déterminer la taille d'un type énuméré en C++ à l'aide de la sizeof de l'opérateur. La taille du type énuméré est la taille de son type sous-jacent. De cette façon, vous pouvez deviner quel type de votre compilateur est à l'aide de votre enum.

Si vous spécifiez le type de votre enum explicitement comme ceci:

enum Color : char { Red=0, Green=1, Blue=2};
assert(sizeof Color == 1);

Vous pouvez ensuite déclarer avant votre enum?

Pas de. Mais pourquoi pas?

En précisant le type d' enum n'est pas réellement partie de la norme C++. C'est un VC++ extension. Il fera partie de C++0x.

Source

15voto

James Hopkin Points 8318

[Ma réponse est fausse, mais j'ai laissé ici, parce que les commentaires sont utiles].

Avant de déclarer les énumérations est non-standard, car les pointeurs pour les différents types d'énumérations ne sont pas garantis pour être de la même taille. Le compilateur peut-être besoin de voir la définition de connaître la taille des pointeurs peuvent être utilisés avec ce type.

Dans la pratique, au moins sur tous les principaux compilateurs, des pointeurs vers les énumérations sont de taille uniforme. Avant la déclaration d'énumérations est fourni comme une extension du langage par Visual C++ par exemple.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X