Partielle Template Spezialisierung



  • Ich schreibe zur Zeit sowas wie ne Traits-Klasse in der ich einen groesseren Parametersatz abhaengig von zwei Parametern kodieren moechte. Aussehen tut das zur Zeit wie folgt:

    //UECOnfig2.h
    enum { DIRECT,
           NOMPI,
           s000_033_066,
           s000_090_095,
           s013_033_066,
           s016_033_066,
           s016_090_095,
           s019_033_066 };
    
    enum { PYTHIA62 = 62,
           PYTHIA64 = 64 };
    
    template <int PARAMSET, int PYTVERSION = PYTHIA64>
    struct PytParams;  // to be defined only for sXXX_XXX_XXX sets
    
    template<int PYTVERSION>
    struct PytParams<s000_033_066, PYTVERSION>  // erster abhaengiger Parametersatz
    {
      template <int PYTV>  struct P81;
    
      template<> struct P81<PYTHIA62>   // line 44
      { enum { min = 11, max = 19 }; }; // line 45
    
      template<> struct P81<PYTHIA64>
      { enum { min = 13, max = 24 }; };
    
      typedef P81<PYTVERSION> PARP81;
    
      enum { CKIN3 = 20,
    	 PARP89 = 1000, 
    	 PARP90 = 0,
    	 PARP85 = 33,
    	 PARP86 = 66 };
    }; 
    
    template<int PYTVERSION>
    struct PytParams<s000_090_095, PYTVERSION> // zweiter abhaengiger Parametersatz
    {
      template <int PYTV>  struct P81;
    
      template<> struct P81<PYTHIA62>
      { enum { min = 11, max = 19 }; };
    
      template<> struct P81<PYTHIA64>
      { enum { min = 12, max = 20 }; };
    
      typedef P81<PYTVERSION> PARP81;
    
      enum { CKIN3 = 20,
    	 PARP89 = 1000, 
    	 PARP90 = 0,
    	 PARP85 = 90,
    	 PARP86 = 95 };
    };
    

    Ich moechte damit in etwa folgende Zugriffe ermoeglichen:

    typedef PytParams<s000_090_095> b1;      // PYTVERSION ist PYTHIA64 
    typedef PytParams<s000_033_066, PYTHIA62> a2;
    
    cout << a2::PARP85 << endl; // 33
    cout << a2::PARP81::min << endl; // 13
    cout << b1::PARP90 << endl; // 0
    cout << b1::PARP81::max << endl; // 20
    

    Mein Problem ist un folgendes: Der Compiler sagt mir

    /blabla/ConfigUE2.h:44: error: explicit
       specialization in non-namespace scope `struct PytParams<2, PYTVERSION>'
    /blabla/ConfigUE2.h:44: error: enclosing class
       templates are not explicitly specialized
    /blabla/ConfigUE2.h:45: error: template
       parameters not used in partial specialization:
    /blabla/ConfigUE2.h:45: error:         `
       PYTVERSION'
    

    Ich ahb offensichtlich irgendwas an der Syntax des inneren class templates nicht gerafft, kann mir jemand auf die Spruenge helfen wo der fehler ist?



  • Hallo,
    du darfst Templates nur auf Namespace-Ebene spezialisieren, du spezialisierst sie aber innerhalb eines Templates. Gibt zwar Compiler, die Spezialisierung innerhalb einer Klasse erlauben (VC 6.0 z.B.), aber das ist dann eine Spracherweiterung.
    Wenn du bei Standard-C++ bleiben willst, musst du dir was anderes überlegen, da du hier eine innere Template-Klasse nicht vollständig spezialisieren kanst ohne die äußere Klasse vollständig zu spezialisieren.



  • Okay, hab mir jetzt folgendes Ueberlegt: ich leite die Klassen, die von mehr Parametern abhaengen, von denen ab, die von weniger abhaengig sind:

    struct ConstParams
    { enum { CKIN = 20, PARP89 = 1000 }; };
    
    template <int PARAMSET>
    struct SetParams;
    
    template <>
    struct SetParams<s000_033_066>
    { enum { PARP90 = 0, PARP85 = 33, PARP86 = 66 }; };
    struct SetParams<s000_090_095>
    { enum { PARP90 = 0, PARP85 = 90, PARP86 = 95 }; };
    struct SetParams<s013_033_066>
    { enum { PARP90 = 13, PARP85 = 33, PARP86 = 66 }; };
    struct SetParams<s016_033_066>
    { enum { PARP90 = 16, PARP85 = 33, PARP86 = 66 }; };
    struct SetParams<s016_090_095>
    { enum { PARP90 = 16, PARP85 = 90, PARP86 = 95 }; };
    struct SetParams<s019_033_066>
    { enum { PARP90 = 19, PARP85 = 33, PARP86 = 66 }; };
    
    template<int PARAMSET, int PYTVERSION>
    struct P81;
    
    template <>
    struct P81<s000_033_066, PYTHIA64>
    { enum { min = 11, max = 19 }; };
    
    // usw.
    
    template<int PARAMSET, int PYTVERSION>
    struct PytParams : public ConstParams, public SetParams<PARAMSET>
    {
      typedef P81<PARAMSET, PYTVERSION> PARP81;
    };
    

    Hoffe mal, dass das funktioniert udn Standardkonform ist...



  • funktioniert auch nicht, weil ich mit dem scope-operator nicht auf geerbte Werte zugreifen kann:

    error: `CKIN3' is not a
       member of type `PytParams<2, 64>'
    

    Jemand ne Idee?



  • Hallo,
    zeig doch mal den Code, der diesen Fehler verursacht.



  • hmm warum überhaupt ConstParams als Basis nutzen?

    Ich sehe dafür eigentlich keinen grund, du könntest das enum genauso gut direkt in PytParams haben

    Ansonsten schließe ich mich auch HumeSikkins an, zeig mal den code der den Fehler verursacht.

    BR
    Vinzenz


  • Mod

    pumuckl schrieb:

    funktioniert auch nicht, weil ich mit dem scope-operator nicht auf geerbte Werte zugreifen kann:
    error: CKIN**3**' is not a member of typePytParams<2, 64>'

    Jemand ne Idee?

    schreibfehler?



  • evilissimo schrieb:

    hmm warum überhaupt ConstParams als Basis nutzen?

    Ich sehe dafür eigentlich keinen grund, du könntest das enum genauso gut direkt in PytParams haben

    kjau habs da mit dem Vererben wohl etwas uebertrieben

    camper schrieb:

    schreibfehler?

    ARGS ja, verdammt.

    Jetzt klappts...


Anmelden zum Antworten