g++ & Templates



  • Moin,

    ich habe momentan ungefähr folgendes Konstrukt als Quellcode vorliegen:

    namespace ns{
            template<int n, int m>
            class A{
                  protected:
                  double a[n][m];
            };
    
            template<int n>
            class B : public A<1,n>{
                 public:
                 void niceMethod(){
                    // Zugriff auf a
                 }
            };
    }
    

    Ich bekomme, sofern ich das Programm mit dem gcc(g++, in der aktuellsten Version 4.4.2) kompiliere, die Fehlermeldung, dass a in diesem Scope - mit Verweis auf niceMethod - nicht existieren würde. Dasselbe Konstrukt kompiliert aber mit dem VS-C++-Compiler in der 2008er-Version ohne Probleme.
    Ich wüsste gerade auch ehrlich gesagt nicht, was ich hier falsch gemacht haben könnte. Da ich schon des öfteren von Problemen beim g++ im Zusammenhang mit Templates gehört hab: Gehört dieses in diese Kategorie?

    Edit:
    Okaaay, ich habe gerade statt der "einfachen" Referenzierung von a in der abgeleiteten Klasse durch

    a[1][2];
    

    mal spaßeshalber

    this->a[1][2];
    

    probiert und es funktioniert jetzt... Damit hat sich das Problem eigentlich auch schon erledigt 😃
    Aber gibt es noch mehr solcher Kuriositäten, auf die ich - besonders im Zusammenhang mit Templates - achten müsste?



  • Der Compiler findet a nicht, da er versucht die Variable vor der Instantiierung zu binden, die Basisklasse aber erst danach vorliegt. Dadurch, dass du this-> davor schreibst verzögerst du die Bindung und dadurch findet der Compiler die Variable. Das macht zum Beispiel in folgendem Fall Sinn:

    int a = 0;
    template<class B>
    class A:B{
      static void f(){ a = 1; }
    };
    
    class B{static int a;}
    

    A<B>::f() setzt dann immer das globale a.

    An einigen stellen musst du vor Typen noch ein typename packen. Bei einigen sehr exotischen Konstrukten brauchst du auch noch template. In der Regel führt das fehlen dieser beiden Schlüsselwörter zu sehr kryptischen Fehlermeldungen.



  • Der Compiler findet a nicht, da er versucht die Variable vor der Instantiierung zu binden, die Basisklasse aber erst danach vorliegt. Dadurch, dass du this-> davor schreibst verzögerst du die Bindung und dadurch findet der Compiler die Variable. Das macht zum Beispiel in folgendem Fall Sinn:

    Ist das im Sprachstandard irgendwo geregelt, wie dieser Fall zu handhaben ist? Mir ist es letztens schon aufgefallen, dass z.B. der g++ mir auch ohne vorherige Instantiierung ab und zu Syntaxfehler um die Ohren knallt, während der VS-C++-Compiler brav auf eine selbige wartet, bevor er Fehler ausspuckt. Müssen Templates überhaupt geparst werden, sofern keine Instantiierung vorliegt?

    Und wie kann der Microsoft-Compiler dein Beispiel auflösen, falls er die Bindung tatsächlich erst bei der Instantiierung vollführt? Nimmt er das globale a, oder das statische Element aus der Basisklasse? (Ich kann es gerade nicht testen)



  • A<1,n>::a[1][2]
    

    ginge auch

    Matzer schrieb:

    Der Compiler findet a nicht, da er versucht die Variable vor der Instantiierung zu binden, die Basisklasse aber erst danach vorliegt. Dadurch, dass du this-> davor schreibst verzögerst du die Bindung und dadurch findet der Compiler die Variable. Das macht zum Beispiel in folgendem Fall Sinn:

    Ist das im Sprachstandard irgendwo geregelt, wie dieser Fall zu handhaben ist? Mir ist es letztens schon aufgefallen, dass z.B. der g++ mir auch ohne vorherige Instantiierung ab und zu Syntaxfehler um die Ohren knallt, während der VS-C++-Compiler brav auf eine selbige wartet, bevor er Fehler ausspuckt. Müssen Templates überhaupt geparst werden, sofern keine Instantiierung vorliegt?

    Und wie kann der Microsoft-Compiler dein Beispiel auflösen, falls er die Bindung tatsächlich erst bei der Instantiierung vollführt? Nimmt er das globale a, oder das statische Element aus der Basisklasse? (Ich kann es gerade nicht testen)

    Ja, das steht im Standard. 14.6 glaube ich. Der GCC implementiert den Standard in der Regel strikter als der VC++. (Vorallem mit -std=c++0x -pedantic-errors -Wall -Wextra). Daher würde ich im Zweifelsfall davon ausgehen, dass der GCC recht hat.


Anmelden zum Antworten