there are no arguments that depend on a template parameter



  • Hallo,

    ich möchte einen neuen Thread aufmachen weil mein Problem jetzt etwaig anders ist und ich übersicht halten will damit ihr schneller zugang zum Problem habt.

    Ich habe folgendes Minimalbeispiel. Ich bitte darum auch die Ordnerstruktur so hinzubiegen wie bei mir damit wir ein und dasselbe Problem behandeln:

    Meine main.cpp liegt in einem Ordner:

    #include <iostream>
    #include "Matrix.h"
    
    int main(int argc, int** argv)
    {
        int c = 7;
    
        Matrix<double> *mtx = new Matrix<double>(c);
    
        std::cout << "jjjjjj" << std::endl;
    }
    

    Meine Matrix.h liegt neben der main.cpp

    #include "Impl_Env.h"
    
    #ifndef INCLUDE_Matrix
    #define INCLUDE_Matrix
    
    template <class T> class Matrix
    {
        public:
            Matrix<T>(int c);
    };
    
    #include "Matrix.imp"
    
    #endif
    

    Und dazu gehört die Matrix.imp die neben der Matrix.h liegt:

    template<class T> 
    Matrix<T>::Matrix(int c)
    { 
        foo(c);
    };
    

    Ich habe eine Impl_Env.h die ebenfalls neben der main.cpp liegt und folgendes beinhaltet (bitte nicht wundern aber hier stehen bei meinem großen beispiel noch andere sachen die aber den fehler nicht beeinflußen):

    #include "variante/Impl.h"
    

    UNd zuletzt noch die Impl.h Datei die in einem Ordner variante liegt. Also unter variante/Impl.h steht:

    #ifndef INCLUDE_IMPL
    #define INCLUDE_IMPL
    
    #include "../Matrix.h"
    
    inline void
    foo(int c)
    {
    
    }
    
    template <class T_Field> inline void
    bar(Matrix<T_Field>* mtx)
    {
    
    }
    
    #endif
    

    Und ich bekomme folgende Fehlermeldung die ich mir nicht erklären kann beim compilieren von meinem Minimalbbeispiel

    g++  -c main.cpp -o main.o
    variante/../Matrix.imp: In constructor ‘Matrix<T>::Matrix(int)’:
    variante/../Matrix.imp:4: error: there are no arguments to ‘foo’ that depend on a template parameter, so a declaration of ‘foo’ must be available
    variante/../Matrix.imp:4: error: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
    make: *** [main.o] Error 1
    

    Wichtig: Ich möchte die Methode bar natürlich benutzen in anderen Klassen die auch Impl.h einbinden. Die muss aber template-abhängig sein.

    Über Hilfe bin ich sehr dankbar!



  • gruppa schrieb:

    // Matrix.h
    #include "Impl_Env.h" // Dies inkludierst du vor der Deklaration von Matrix<T>
    //...
    template <class T> class Matrix
    //...
    #include "Matrix.imp"
    //...
    

    Ich tippe hier einen klassischen Kreisverweis. Was war zuerst: Henne oder Ei?

    Zudem inkludierst du in der Matrix.h deine Impl_Env.h (Damit indirekt deine variante/Impl.h) außerhalb der Includeguards. Ich hoffe mal das du in Impl_Env.h außen Includeguards auch um die includes setzt... Sonst würde hier der Compiler noch ganz andere Probleme bekommen...

    Ob ich damit richtig liege weiß ich nicht, dazu ist der Codeausschnitt nicht ausführlich genug. Ich tippe auch etwas auf einen Designfehler, aber auch dies kann ich nicht verifizieren.

    cu André


  • Mod

    Hier wird erklärt wie es zu deinem Problem kommt:
    http://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html

    Leider ist dein Code etwas wirr, weshalb ich jetzt nicht auf die genaue Stelle zeigen kann, an der du deinen Fehler machst. Aber da du einen besseren Überblick haben dürftest, sollte die Erklärung des Fehlers dir weiterhelfen können.

    edit: Kurze deutsche Erklärung: An der Stelle wo Matrix<T>::Matrix(int c) definiert wird muss foo() bekannt sein. Der Compiler meldet hier nicht wie sonst eine 'undefined reference', weil dies bei templates sonst eigentlich nicht nötig ist und er dich darauf aufmerksam machen möchte, dass hier ein Sonderfall vorliegt.

    Um Rauszufinden, warum foo() an betreffender Stelle nicht bekannt ist, kannst du bei deinem Include-Gewirr ja mal

    g++ main.cpp -E
    

    verwenden. Das zeigt dir an, wie der Präprozessor deinen Code zusammensetzt (Mach aber vorher das #include<iostream> raus!). Da dürfte sich dann ergeben, dass foo() irgendwo hinter Matrix<T>::Matrix(int c) landet.



  • Ok - erstmal danke euch.

    Lasse ich mir ausgeben was der Präprozessor macht mit obigem code landet foo() tatsächlich hinter Matrix. Füge ich allerdings das Include in Matrix.h in die Includeguards landets davor und es kommt die Meldung:

    variante/Impl.h:13: error: variable field 'bar' declared void
    variante/Impl.h:13: error: 'bar' declared as an 'inline' variable
    variante/Impl.h:13: error: template declaration of 'int bar'
    variante/Impl.h:13: error: 'Matrix' was not declared in this scope
    variante/Impl.h:13: error: expected primary-expression before '>' token
    variante/Impl.h:13: error: 'mtx' was not declared in this scope
    

    Mit dem Link weiß ich nicht so recht umzugehen. Ich kann weder eine Base-Class davor schreiben noch den this-> pointer weil die Klasse Matrix ja keine definition von foo() hat.

    Ich steh bei dem Problem vollkommen auf dem Schlauch und weiß mittlerweile gar nicht ob sich das irgendwie lösen lässt...
    Was könnte ich noch tun - ich probiere blind rum



  • würde es sauber sein aus Matrix.h das #include "Impl_Env.h" zu streichen und es dafür in Matrix.imp zu schreiben bzw. vor das #include "Matrix.imp" zu schreiben - so ginge es nämlich....



  • scheiße...doch nicht - zumindest mein normaler code geht da net. ich werd noch verrückt



  • vielleicht hole ich etwas aus weil einige vielleicht denken das wäre ein design-fehler:

    Ich habe eine Idee von Shade übernommen dass ich compilerbedingte #ifdef-strukturen in separate dateien auslagere die ich dann einmal über ein file includiere (Impl_Env.h oben).

    Der Thread zu dem Thema ist hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-236515-and-highlight-is-ifdef.html

    Deswegen ist die Struktur vielleicht etwas verwirrend. Jetzt benutze ich aber templates und komme in Teufels küche. Wie würdet ihr das lösen MIT dieser auslagerungs-struktur...kann ich irgendwo was verbessern?



  • *push



  • gib uns nochmal ein wenig Code, der Überischt halber...


Log in to reply