Zum Inhalt springen

C++: Enum-Iteration


FighterFigger

Empfohlene Beiträge

Hallo Mädels und Jungx,

ich möchte gerne über einen Enum iterieren, befinde mich aber in einem Zeit-kritischen Bereich (ca. 5 Mio. Aufrufe dieses Blocks)

In C++ sieht das bei mir so aus:

// - enum ----------------------------------------------

namespace defs

{

enum
months

{
JANUARY,

FEBRUARY,

...

DECEMBER,

LAST_MONTH

};}

// - enum ----------------------------------------------

...

// - block ----------------------------------------------

for (int month = defs::JANUARY; month < defs::LAST_MONTH; month++)

{

function(defs::months(month));
// <---- function nimmt ein Element des Enums

}

// - block ----------------------------------------------

Ich weiß, daß ich optimieren könte, wenn ich von vornherein mit Integern plane, ich möchte die Enums gerne der Übersicht wegen weiterhin nutzten.

Fragen:

1. Weiß jemand, wie Aufwendig der Operator (oder Konstruktor) ist, der einen Integer in ein Enum-Element zurück wandelt?

2. Wird dieser Operator vielleicht sogar durch MS-C++-Compiler wegoptimiert?

Denn selbst, wenn ich den ++Operator für das Enum definiere scheine ich um diesen Operator (oder ist das ein Konstruktor) nicht umher zu kommen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke für die Antwort, aber bis zur Iteration ist noch alles klar. Ekelig hingegen wird es dann bei der Funktion function.

void function(defs::months myMonth);

Diese Funktion nimmt einen Wert des Types defs::months und bei C++ reicht da ein Integer nicht aus, ich muß diesen erst konvertieren mit defs::months(int i)

Und diese Konversion ... wie lange dauert diese, und wird sie durch Compiler optimiert oder nicht?

Gruß - ich :e@sy

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

Diese Funktion nimmt einen Wert des Types defs::months und bei C++ reicht da ein Integer nicht aus.

Doch, da reicht ein Integer völlig aus. Enums werden intern als Integers behandelt. D.h. auch bei der Übergabe an Funktionen wird ein Integer übergeben (nicht etwa JANUARY oder FEBRUARY als String, es findet daher auch keine Konvertierung statt). Jeder halbwegs brauchbare Compiler wird Optimierungen vornehmen, so dass der Integer in einem Register an die Funktion übergeben wird. Ein guter Compiler generiert Code bei dem es kein Unterschied macht, ob Du ein Parameter an die Funktion übergibst oder nicht, da sich der Parameter beim Aufruf bereits im entsprechenden Register befindet (das ist unter Umständen auch abhängig von der Prozessorarchitektur auf der Du arbeitest).

Probiere mal folgendes aus:


#include <iostream.h>

namespace defs
{
enum months
{
JANUARY,
FEBRUARY,
MARCH,
APRIL,
MAY,
JUNE,
JULY,
AUGUST,
SEPTEMBER,
OCTOBER,
NOVEMBER,
DECEMBER,
LAST_MONTH
};
}

void function(defs::months myMonth)
{
cout << myMonth << endl;
}

int main()
{
for (int month = defs::JANUARY; month < defs::LAST_MONTH; month++)
function(defs::months(month));
}

[/php]

Nic

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo nic_power,

In der folgenden Codezeile deines Codes rufst du auch diesen Konstruktor (oder ist es ein Operator) auf, da eben in C++ nicht einfach nur ein Integer übergeben werden kann. Dieser Konstruktor (oder ist es ein Operator?) heißt so, wie der Enum-Typ

   function(defs::months(month)); 

Das Problem ist ja, daß ein Enum mehrere Einträge mit identischem Wert haben kann. Also hat zwar jeder EnumWert genau einen Integer zugewiesen, aber ein Integer kann einen, keinen oder mehrere Enumtypen zugeordnet haben.

Sucht mein Programm immer nach dem Enum, mit der entsprechenden Zahl, oder akzeptiert er die Zahl, wie sie ist ...

Also sehe ich das richtig ... in der Laufzeit existiert diese Konversion gar nicht mehr, sondern die ist nur für den Compiler - so wie ein cast?

Gruß - ich :D

Link zu diesem Kommentar
Auf anderen Seiten teilen

In der folgenden Codezeile deines Codes rufst du auch diesen Konstruktor (oder ist es ein Operator) auf, da eben in C++ nicht einfach nur ein Integer übergeben werden kann.

Ich verstehe nicht was du damit meinst das nicht einfach nur ein Integer übergeben werden kann. Es wird der Funktion function nur ein Integer übergeben, da sich hinter den einzelnen Elementen des Enums nichts anderes verbirgt.

Man könnte es fast mit einem #define vergleichen, nur das ein definierter Wert vom Präprozessor ausgetauscht wird und das Enum, so weit ich weiß, wie eine normale Variable behandelt wird.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

Das Problem ist ja, daß ein Enum mehrere Einträge mit identischem Wert haben kann. Also hat zwar jeder EnumWert genau einen Integer zugewiesen, aber ein Integer kann einen, keinen oder mehrere Enumtypen zugeordnet haben.

Wo hast Du denn diese Information her? Die Namen der Enumeratoren innerhalb eines Scopes müssen unterschiedlich sein. Dabei könnern innerhalb einer Enumeration durchaus identische Werte verwendet werden. Der Wert muss jedoch immer entweder ein integer sein, oder ein Wert welcher entsprechend konvertiert werden kann ("integral promotion", dies ist jedoch keine echte Konvertierung, der Datentyp wird vielmehr auf ein Integer "erweitert"); dazu gehören char, short int usw. Das kannst Du überprüfen, indem Du die Zeile "SEPTEMBER" in "SEPTEMBER=30" änderst und das Programm dann nochmals laufen läßt.

Nic

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich verstehe nicht was du damit meinst das nicht einfach nur ein Integer übergeben werden kann. Es wird der Funktion function nur ein Integer übergeben, da sich hinter den einzelnen Elementen des Enums nichts anderes verbirgt.

Hi Guybrush,

ich meine damit, daß folgendes nicht funktioniert:

function(10);

und auch nicht:

int monat = 10;
function(monat);[/PHP]

beides führt zu fehlern. Es geht erst wenn:

[PHP]function(defs:months(10));

oder:

int monat = 10;
function(daef::months(monat));[/PHP]

Also kann ich nur kompilieren, wenn ich [i]defs::months(...)[/i] hinzufüge. Beeinflußt dieser Zusatz nun also die Laufzeit oder ist das nur für den Compiler?

und [b]nic_power[/b]:

ich meinte sowas:

[PHP]enum zahlen
{
EINS = 1,
ZWEI,
ZWO = ZWEI,
DREI = 3,
VIER,
VIELE = 10
};

in diesem Enum ist die 2 zweimal vertreten, für 5 bis 9 gibt es aber keinen Enum. (also jeder Wert nur max einmal, aber Integer können öfter oder sogar gar nicht auftreten)

Wie handelt der während der Laufzeit folgende Aufrufe:

zahlen(2);   // Aufruf 1
zahlen(6); // Aufruf 2[/PHP]

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...