[bug im VS8?] static template-class member



  • //x.h
    template< typename value_type=double>
    class BaseClass
    {
    public:
       static std::vector< std::vector<value_type> > scale_factor; 
       static value_type temperature;
    };
    
    template< typename value_type> 
    std::vector< std::vector<value_type> > Klasse<value_type>::scale;
    template< typename value_type> 
    value_type Klasse<value_type>::temperature = 27.0;
    
    template< typename VectorClass >
    class DerivedClass: public BaseClass< typename VectorClass::value_type >
    {
    //...
    inline void scale() { this->temperature = 28.0; /*...*/}
    //...
    };
    

    hierbei tritt mit VS 2005 Sp1 folgendes Problem auf:
    Die Datei x.h wird des Öftern inkludiert. Aber nicht alle unsere Projekte verwenden scale/temperature dieser Klasse, binden diese Datei jedoch aufgrund Verwendung anderer Klassen ein. Es wird also je nach Projekt nirgends BaseClass::temparatur = 29; o.ä. aufgerufen und auch die scale Werte bleiben in einem solchen Fall unangetastet. Ich möchte hie rnicht weiter ins Detail gehen, aber es gibt eben mehrere Rechenmodelle die verschiedene BaseClass-Klassen verwenden. DerivedClass wird dann immer in Form eines template Parameters übergeben:

    //x2.h
    #include "x1.h"
    //...
    template< typename EineDerDerivedClasses >
    class BerechnngsKlasse
    {
    EineDerDerivedClasses mScaler;
    //...
    inline void calc() { /*...*/ mScaler.scale(); /*...*/};
    //...
    
    //x3.h
    #include "x2.h"
    //...
     switch(model)
     {
     case MODEL1: BerechnngsKlasse< DerivedClass1<double> >();
     case MODEL2: BerechnngsKlasse< DerivedClass2<double> >();
     //...
     }
    };
    

    und wenn ich nun in einem Projekt keine cpp habe, die die statischen member zumindest einmal nennt:

    //x.cpp
    #include "x1.h"
    Klasse<>::temperature;
    

    dann erhalte ich die Linker-Fehler: LNK2001 und LNK2019.
    Allerdings verstehe ich nicht wieso, denn im Header definiere ich die statischen Member doch brav. Zudem zickt weder das 2008er Studio noch ein andere von mir zur Verfügung stehender GNU compiler (gcc3.3-4.2, icpc, mingw) rum.
    Hat jemand eine Ahnung woran das liegen koennte?



  • Hast du dich hier verschrieben?

    template< typename value_type> 
    std::vector< std::vector<value_type> > Klasse<value_type>::temperature = 27.0; 
    
    // statt
    value_type BaseClass<value_type>::temperature = 27.0;
    


  • template< typename value_type=double>
    class BaseClass
    {
    public:
       static std::vector< std::vector<value_type> > scale_factor;
       static value_type temperature;
    };
    
    template< typename value_type>
    std::vector< std::vector<value_type> > Klasse<value_type>::scale;
    template< typename value_type>
    std::vector< std::vector<value_type> > Klasse<value_type>::temperature = 27.0;
    

    Beide definitionen stimmen nicht mit der Deklaration überein. Beim ersten ist der Name verschieden (scale und scale_factor), beim zweiten der Typ (value_type und vector<vector<value_type> >)

    Falls das nicht der Fehler ist, wäre es für nicht-VS-Benutzer noch schön zu wissen, was LNK2001 und LNK2019 für eine Bedeutung haben...



  • ups, ja copy&pase error (verbessert).

    error 2001:
    Nicht aufgelöstes externes Symbol "Symbol"
    unresolved external symbol "symbol"

    error 2019:
    Verweis auf nicht aufgelöstes externes Symbol 'Symbol' in Funktion 'Funktion'
    unresolved external symbol 'symbol' referenced in function 'function'

    jeweils auf die statischen member.



  • okay, ich glaub ich habe die lösung gefunden!

    //x.h
    //...
    template< typename VectorClass >
    class DerivedClass: public BaseClass< typename VectorClass::value_type >
    {
      typedef BaseClass< typename VectorClass::value_type > Base;
      inline void scale() 
      { 
         this->temperature = 28.0; //<-geht nicht
         Base::temperature = 28.0; //geht
      }
      //...
    };
    

    ich vermute, dass der compiler hie reinfach nicht klar kam, zumal man auf statische member eh nich tmit this zugreifen sollte


Anmelden zum Antworten