Enumeration forward-deklarieren



  • Hallo,

    kann man eigentlich eine Enumeration forward-deklarieren? Meine Versuche waren nicht erfolgreich, mein Code sieht so aus:

    #ifndef ALPHABET_H_
    #define ALPHABET_H_
    
    enum StateType;
    
    class TransAlphabet
    {
    public:
      void init(enum StateType transitions);
    };
    
    #endif
    
    #include "standard.h"
    #include "error.h"
    #include "profileHMM.h"
    #include "alphabet.h"
    
    using namespace std;
    
    void TransAlphabet::init(enum StateType transitions) {
    
    }
    

    und fuehrt zu der Fehlermeldung

    g++ -c -Wall -ansi -pedantic -g -ggdb -O0 -DDEBUG -o alphabet.o alphabet.cpp -I /home/ingo/libs/boost/ 
    In file included from alphabet.cpp:1:
    alphabet.h:6: Fehler: Verwendung des enum »StateType« ohne vorherige Deklaration
    alphabet.h:11: Fehler: Verwendung des enum »StateType« ohne vorherige Deklaration
    alphabet.cpp:8: Fehler: Verwendung des enum »StateType« ohne vorherige Deklaration
    make: *** [alphabet.o] Fehler 1
    


  • Geht leider nicht.



  • Das geht deshalb nicht, weil die Größe einer Enumeration von der Anzahl der Elemente abhängig sein kann. Der kommende Standard führt die Option ein, explizit eine Enum-Größe anzugeben:

    enum MyEnum : int { ... };
    

    Für solche Enumerationen sind dann Forward-Deklarationen möglich.



  • audacia schrieb:

    Das geht deshalb nicht, weil die Größe einer Enumeration von der Anzahl der Elemente abhängig sein kann....

    Hieße das, dass das mit Zeigern/Referenzen ginge?

    enum StateType;
    
    class TransAlphabet {
    public:
      void init(StateType& transitions);
    };
    

    ... oder ist das einfach so verboten?

    Gruß,

    Simon2.



  • Simon2 schrieb:

    ... oder ist das einfach so verboten?

    Ich nehme an, daß es so ist. Vielleicht, weil man in der Praxis ungefähr nie einen enum-Wert per Referenz oder gar per Zeiger übergibt.



  • audacia schrieb:

    Der kommende Standard führt die Option ein, explizit eine Enum-Größe anzugeben:

    enum MyEnum : int { ... };
    

    Für solche Enumerationen sind dann Forward-Deklarationen möglich.

    Wieder ein weiteres sehr nettes Feature, auf das ich mich freuen kann. 🙂

    Die nicht mögliche Vorwärtsdeklaration von enum s ist schon mühsam. Auch diejenige von Nested Types. Falls das auch noch einmal kommen sollte, sind wir diesbezüglich schon nahe an der Perfektion. 😉

    Edit: @ Simon2:
    Nur weil du nicht gerade das beste Beispiel genommen hast und das ein verbreiteter Irrtum ist:

    class A; // Klassen-Vorwärsdeklaration
    
    class B
    {
        void Function(A a); // <- Kopie!
    };
    

    Das ist sehr wohl möglich.



  • audacia schrieb:

    Simon2 schrieb:

    ... oder ist das einfach so verboten?

    Ich nehme an, daß es so ist. Vielleicht, weil man in der Praxis ungefähr nie einen enum-Wert per Referenz oder gar per Zeiger übergibt.

    Nunja ansonsten spricht der Standard oft genug kein Verbot aus für Dinge, die in den allermeisten Fällen sinnlos/unüblich sind. 😉
    Aber vielleicht kommt das Verbot noch aus früheren Zeiten.

    Gruß,

    Simon2.



  • Nexus schrieb:

    audacia schrieb:

    Der kommende Standard führt die Option ein, explizit eine Enum-Größe anzugeben:

    enum MyEnum : int { ... };
    

    Für solche Enumerationen sind dann Forward-Deklarationen möglich.

    Wieder ein weiteres sehr nettes Feature, auf das ich mich freuen kann. 🙂

    Mein Compiler kann das 😉

    Nexus schrieb:

    Die nicht mögliche Vorwärtsdeklaration von enum s ist schon mühsam. Auch diejenige von Nested Types. Falls das auch noch einmal kommen sollte, sind wir diesbezüglich schon nahe an der Perfektion. 😉

    Meinst du so etwas:

    class Outer
    {
        struct Inner;
        Inner* theData;
    };
    ...
    struct Outer::Inner
    {
        ...
    };
    

    Das ist bereits in aktuellem C++ möglich.



  • @ audacia:
    Nein, ich meinte eher sowas.



  • Nexus schrieb:

    ...@ Simon2:
    Nur weil du nicht gerade das beste Beispiel genommen hast und das ein verbreiteter Irrtum ist:

    class A; // Klassen-Vorwärsdeklaration
    
    class B
    {
        void Function(A a); // <- Kopie!
    };
    

    Das ist sehr wohl möglich.

    Du hast natürlich recht: In diesen Dingen bin ich nicht ganz sattelfest ... aber deshalb hatte ich audacias Aussage

    audacia schrieb:

    Das geht deshalb nicht, weil die Größe einer Enumeration von der Anzahl der Elemente abhängig sein kann. ...

    in der Richtung verstanden: "... und weil der Compiler an dieser Stelle die Größeinformation braucht."

    Das erinnerte mich (wie Du vermutlich weißt) an

    struct A;
    struct B {
     A a;
    };
    

    was ja (wenn ich nicht auch das falsch in Erinnerung habe) NICHT geht.

    Liegt dann das "enum-foward-declaration-Verbot" gar nicht an der fehlenden/variablen Größeninformation? Oder hat diese noch andere Auswirkungen?

    Danke für die Aufklärung!
    Gleich, um diese Lücke zu schließen: Gilt das dann auch für "freie" Funktionen?

    struct A;
    void f(A a); // ?
    A f();  // ?
    

    Gruß,

    Simon2.


Anmelden zum Antworten