Zwei Aufzählungen haben einige Elemente gemeinsam, warum erzeugt dies einen Fehler?
Lesezeit: 4 Minuten
Peter
Ich habe zwei Enums in meinem Code:
enum Month {January, February, March, April, May, June, July,
August, September, October, November, December};
enum ShortMonth {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
May ist ein gemeinsames Element in beiden Aufzählungen, also sagt der Compiler:
Neudeklaration des Enumerators ‘May‘.
Warum sagt es das? Und wie kann ich das umgehen?
entspannen
Aufzählungsnamen sind global gültig, sie müssen eindeutig sein. Denken Sie daran, dass Sie die Aufzählungssymbole nicht mit dem Aufzählungsnamen qualifizieren müssen, sondern nur:
Month xmas = December;
nicht:
Month xmas = Month.December; /* This is not C. */
Aus diesem Grund sehen Sie oft Leute, die den Symbolnamen den Namen der Aufzählung voranstellen:
enum Month { Month_January, Month_February, /* and so on */ };
Gibt es dennoch ein Szenario, in dem die beiden Namen in Konflikt geraten könnten? Können sie beispielsweise einer Aufzählung ihres eigenen Typs zugewiesen oder mit ihr verglichen werden? Oder sind es nur Compiler-Autoren, die beschützend (oder faul) sind?
– SF.
29. Januar 2010 um 12:49 Uhr
Damit beide Definitionen möglich sind, benötigen Sie eine überladende Auflösung unter Berücksichtigung des Verwendungskontexts. In C gibt es keine Überladung (auf Benutzerebene). Und in C++ berücksichtigt die Überladungsauflösung nicht den Verwendungskontext (mit Ausnahme der impliziten Konvertierung).
– Ein Programmierer
29. Januar 2010 um 12:54 Uhr
@SF: Stellen Sie sich zwei Aufzählungen vor: Colors und Fruits. Was wäre der Wert von Orange?
– mouviciel
29. Januar 2010 um 12:55 Uhr
Eine Aufzählung hat in C den Typ int, es ist kein separater Typ. Einige Compiler warnen jedoch, wenn Sie es mit anderen Aufzählungen vergleichen.
– Nr
29. Januar 2010 um 12:56 Uhr
@nos “enum hat einen int-Typ” Hmmm, dachte ich enum könnte verschiedene Typen haben: Art.-Nr.
Um Namenskonflikte zu vermeiden, könnten Sie in C++ Ihre Aufzählungen in Strukturen einpacken:
struct Month { enum {January, February, March, April, May, June, July,
August, September, October, November, December}; };
struct ShortMonth { enum {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec}; };
Ja, aber das Problem des Themenstarters tritt auch in C++ auf. Daher denke ich, dass es auch für C++-Leute nützlich sein könnte. Beitrag bearbeitet, um diese Änderung widerzuspiegeln.
– Alexander Poluktow
29. Januar 2010 um 13:22 Uhr
Oder verwenden enum class oder auch namespace
– o11c
26. Juni 2015 um 0:04 Uhr
In C++11 können Sie verwenden Bereichsbezogene Aufzählungen um dies zu beheben. Dadurch werden die Namen aus dem globalen Gültigkeitsbereich entfernt und auf den Aufzählungsnamen beschränkt.
enum class Identity
{
UNKNOWN = 1,
CHECKED = 2,
UNCHECKED =3
};
enum class Status
{
UNKNOWN = 0,
PENDING = 1,
APPROVED = 2,
UNAPPROVED =3
};
int main ()
{
Identity::UNKNOWN;
Status::UNKNOW;
}
Was Entspannung gesagt hat. Aber ich möchte auch sagen, dass Ihr Beispiel eine ziemlich ungewöhnliche Verwendung von Aufzählungen zu sein scheint. Ich kann den Wert eines ShortMonth und eines LongMonth nicht erkennen, die sich beide auf dasselbe beziehen – dies wäre für Zeichenfolgen sinnvoll, aber nicht für Aufzählungen. Warum nicht einfach einen einzigen Month-Enumerationstyp haben?
Fortran
Mein Vorschlag hier ist, nur eine Aufzählung zu haben, da sie vom gleichen Typ sind. Wenn Sie möchten, dass kurze Aliase weniger in Ihren Code eingeben (auch wenn ich Ihnen nicht dazu raten würde), können Sie Folgendes tun:
enum Month {
January, Jan = January,
February, Feb = February,
March, Mar = March,
April, Apr = April
May,
June, Jun = June,
July, Jul = July,
...};
Und um unterschiedliche Präsentationsnamen (kurz und lang) zu haben, sollten Sie zwei unterschiedliche String-Arrays haben, die durch die Aufzählung indiziert werden.
char[MAX_MONTH_NAME_LENGTH][12] month_long_names = {
"January", "February", ...
}
char[3][12] short_long_names = {
"Jan", "Feb", ...
}
printf("month %d long name is %s, and short name is %s\n", May, long_month_names[May], short_month_names[May]);
Morfildur
In C werden Aufzählungen ohne Typpräfix verwendet, also schreiben Sie:
month[0] = January;
month[4] = May;
Die Aufzählung Month und ShortMonth haben denselben Gültigkeitsbereich, sodass der Compiler nicht wissen kann, welcher May verwendet werden soll. Eine offensichtliche Lösung wäre, den Aufzählungen ein Präfix voranzustellen, aber ich bin mir nicht sicher, ob Ihre Verwendung dieser Aufzählungen in diesem Fall gerechtfertigt ist.
13941100cookie-checkZwei Aufzählungen haben einige Elemente gemeinsam, warum erzeugt dies einen Fehler?yes