-5
votes

Affectation à Enum - Lvalue requise dans C / C ++

en attachant mes mains sur Enum J'ai trouvé que:

  1. Enum ne peut être attribué de type littéral (même de types intégrés). XXX

    Concern ce que je ne peux pas comprendre comment Enum n'est pas un lvalue car il a un nom (identifiant).

    1. dans C ++ Primer Il a été donné que:

      Un objet de type d'énumération peut être initialisé ou attribué uniquement par l'un de ses énumérateurs ou par un autre objet du même type d'énumération.

      il a également montré dans un exemple que: xxx

      mais pourquoi sur l'attribution de la valeur correcte tout ce que je reçois est Le même lvalue erreur montré en point 1 .

c c++

5 commentaires

"Un objet de type d'énumération" n'est pas la même chose qu'un "énumérateur". Vous essayez d'attribuer une valeur à un énumérateur et non un objet de type d'énumération. Comparez: signe S; S = alpha;


Il a un nom, mais on ne peut en être attribué de nouveau, car il a une valeur constante par construction (ici 0). Changez votre livre, lancez-le est un incendie.


alfa n'est pas un lvalue, seul LValue peut être attribué


Lorsque vous utilisez C ++, vous devez généralement préférer Enum Class via un Enum .


@Jesperjuhl est-ce une partie de la version avant C ++ 11? (Comme le projet que je travaille exige cela).


3 Réponses :


0
votes

Lorsque vous faites xxx

c'est presque exactement équivalent à xxx

alpha et bêta sera équivalent à 0 et 1 respectivement, et juste comme C / C ++ ne vous permet pas d'attribuer à 0 ou 1 , les constantes de l'énumérateur seront donc non attribuables.

(en plus des constantes d'entier, Enum signe {alpha, bêta} crée également un type entier appelé Enum signe , dont le débogueur peut imprimer comme alpha et bêta au lieu de 0 0 et < Code> 1 , plus les constantes d'énumérateur respectent le scopage et et #define s, mais sinon int #define s et Les constantes d'énumérateur sont fondamentalement interchangeables.)


8 commentaires

C'est presque pas équivalent à cela du tout


@Lightnessrsinorbit Comment figurez-vous? Après prétraitement et sans utiliser de débogueur, je ne pense pas que vous puissiez distinguer alpha et bêta à partir de 0 et 1 dans C.


Ce sont des choses totalement différentes. L'un est un nom dans une portée avec un type; L'autre, après prétraitement, est un littéral entier. Et simplement parce que quelque chose est une pranisation constante ne signifie pas que c'est un littéral (bien que des littéraux non stricts sont des prelures constantes). (Ceci est particulièrement clair avec des énormes encadrées.) Bien sûr, vous pouvez écrire un programme pour lequel la différence n'est pas observable après la compilation, mais c'est vrai pour des charges de choses.


@LightnessRacesInorbit Speed ​​de Scoping, je ne pense pas que vous puissiez (au moins pour les constantes de l'énumérateur de CLI CLAI), observez la différence même pendant la compilation post-prétraitement. Que dans mon livre les rend presque équivalents (ou du moins pas "presque pas du tout équivalent").


Coliru.stacked-crooked.com/a/A6BB111B64DDA208 constantes et macros sont des choses fondamentalement différentes .


@LightnessRacksinorbit, c'est pourquoi je continue à dire après / après le prétraitement.


Mais le problème que j'ai démontré est post-prétraitement visible. C'est le compilateur qui rejette le code, car le programme prétraité contient un appel à une fonction inexistante. Si votre argument est "Il n'y a pas de différence autre que les différences" alors je suis d'accord!


Le pédaltisme sur la reproduction des cas de bord de côté, nous avons un temps suffisamment difficile, car il enseigne aux personnes les différences entre les constantes et les macros de préprocesseur, et je pense qu'il est important de ne pas aussi floue de cette ligne lorsque nous n'avons pas besoin. Un énumérateur et une définition de préprocesseur ne sont que des choses fondamentalement différentes, vivant dans différentes catégories de choses, et je ne vois pas une raison de mentir à ce sujet!



1
votes

Vous pouvez initialiser vos énumérateurs à l'intérieur de la liste énumératrice, non en dehors de celui-ci: xxx pré>

alfa code> n'est pas un "un objet de type d'énumération " em>, c'est un Enumerator . Si vous aviez: p> xxx pré>

alors myenum code> serait "un objet de type d'énumération" em> et ensuite vous pourriez faire: p> xxx pré>

ou: p>

enum class p1 { var1A, var1B };
enum class p2 : std::underlying_type<p1>::type { var2A = p1::var1A, var1B = var1A};


0 commentaires

1
votes

Juste parce que quelque chose a un nom, cela ne signifie pas que c'est un lvalue . C'est plus compliqué que par rapport à. Par exemple, les types ont des noms et ils ne sont pas des valeurs du tout! Vous pensez probablement aux expressions qui utilisent le nom d'une variable , qui ont tendance à être des lvalues. Mais un énumérateur n'est pas une variable.

Les énumérateurs ne sont pas seulement des constantes, mais elles sont également privalues ​​, donc non seulement le message d'erreur correct, mais il est également libellé correctement.

Vous pouvez lire sur Catégories de valeur sur CPPrefreence.com .

Si votre livre dit que var2a = var2b est valide, vous auriez besoin d'un nouveau livre, car c'est un non-sens. Mais le passage cité ne supporte pas votre assertion. Il dit que vous pouvez créer un signe frais et l'initialise à partir de l'une de ces énumérations, comme signe mysign = var2a; . .


2 commentaires

C'est très certainement pas un lvalue. Il ne désigne pas un objet et vous ne pouvez pas prendre son adresse => pas un lvalue.


@Pskocik là-bas.