Kompilierfehler mit g++



  • Hi,
    folgender Beispielcode:

    template<int I>
    class Foo
    {
    public:
        struct Struct
        {
        };
    };
    
    template<int I>
    class Bar
    {
    public:
        typedef Foo<I> FooBar;
        typedef FooBar::Struct FooStruct; // <<< Zeile 20
    };
    

    g++ (4.1.2) kompiliert den Code nicht. Meldung:

    Main.cpp:20: error: type ‘Foo<I>’ is not derived from type ‘Bar<I>’
    Main.cpp:20: error: expected ‘;’ before ‘FooStruct’
    

    Ich kann damit absolut nichts anfangen.
    Kommentiere ich Zeile 20 aus (nur diese!), funkioniert das Kompilieren.
    Ersetze ich FooBar::Struct durch Foo<I>::Struct aendert sich nichts.
    VS 2005 Express kompiliert es (glaube ich, kanns gerade nicht testen, vorhin ging es, habe aber noch ein paar Aenderungen machen muessen).

    Funktioniert er bei euch? Oder sieht jemand einen Fehler?

    Gruss,
    DeSoVoDaMu



  • Argh...es fehlte noch ein "typename" vor FooBar::Struct. Passiert mir doch immer wieder...
    Wenigstens ein Compiler gibt hier vernuenftige Fehlermeldungen 🙂

    Hat vllt jemand eine ordentliche Erklaerung, warum da typename stehen muss?
    Habe auf die Schnelle das hier gefunden http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=/com.ibm.vacpp6m.doc/language/ref/clrc16keyword_typename.htm
    aber irgendwie sind doch beide Beispiele nicht auf meins zu beziehen. Es kann nicht als Funktionsaufruf interpretiert werden und "ill-formed" ist es doch auch nicht 😕

    naja...
    gn8 all



  • DeSoVoDaMu schrieb:

    aber irgendwie sind doch beide Beispiele nicht auf meins zu beziehen.

    Ganz einfach: *jeder* verschachtelte Typ, dessen umgebender Typ von einem Typenparameter abhängt, muss mit 'typename' versehen werden.

    Also:

    template <typename T>
    struct vector {
        typedef /* … */ iterator;
    };
    
    template <typename T>
    struct test {
        typename vector<T>::iterator i;
        typedef typename vector<T>::iterator It_t;
        // Aber hier ohne 'typename':
        It_t j;
        vector<int>::iterator k;
    };
    

    /EDIT: Noch'n Fall hinzugefügt.


Anmelden zum Antworten