problem bei mischung template und enum



  • template <class tresult, class targument, unsigned int n>
    class cmonomial
    {
    	public:
     		//...
    		enum monomial_order {LEX, GRLEX, GREVLEX};
    
    		static void set_order(monomial_order order);
    		static int get_order();
    
    	private:
    
    		static monomial_order _order;
    
    };
    
    template <class tresult, class targument, unsigned int n>
    cmonomial<tresult, targument, n>::monomial_order cmonomial<tresult, targument, n>::_order = cmonomial<tresult, targument, n>::LEX;
    

    da bekomme ich folgende fehlermeldung

    warning C4346: 'cmonomial<tresult,targument,n>::monomial_order' : dependent name is not a type
            prefix with 'typename' to indicate a type
    

    damit kann ich aber irgendwie nicht viel anfangen, vllt hat ja wer nen vorschlag.



  • cmonomial -> momomial 😃



  • FreakyBKA schrieb:

    damit kann ich aber irgendwie nicht viel anfangen, vllt hat ja wer nen vorschlag.

    Prefix 'cmonomial<tresult,targument,n>::monomial_order' with 'typename'.



  • deswegen versteh ich aber trotzdem nicht warum man das typename brauch?


  • Mod

    FreakyBKA schrieb:

    deswegen versteh ich aber trotzdem nicht warum man das typename brauch?

    Weil die Grammatik sonst mehrdeutig ist. Sinn der Sache ist es, Fehler möglichst schon aufspüren zu können, bevor wir das Template instantiieren.
    ob du

    cmonomial<tresult, targument, n>::monomial_order
    

    oder

    cmonomial<tresult, targument, n>::_order
    

    schreibst - woher soll der Compiler wissen, dass das eine ein Typ ist und das andere nicht? Das ist aber wichtig - im ersten Fall haben wir es dann in der Regel mit einer Deklaration zu tun, im anderen Fall mit einem Ausdruck. Mit Sicherheit wissen wir das aber erst, wenn wir die Templateargumente haben. Es könnte ja zum Beispiel immer noch (zur Not erst später - oder gar nicht! - definiert) Spezialiserungen geben, wo alles anders ist. Die Definition des Primärtemplates wird hier gar nicht benötigt, du könntest auch schreiben:

    template <class tresult, class targument, unsigned int n>
    class cmonomial;
    template <class tresult, class targument, unsigned int n>
    typename cmonomial<tresult, targument, n>::monomial_order cmonomial<tresult, targument, n>::_order = cmonomial<tresult, targument, n>::LEX;
    

    (natürlich musst du das Template irgenwann mal wenigstens für Spezialisierungen, die du nutzt, definieren - aber für obige Definition ist es nicht notwendig). Durch die Verwendung von typename sagst du dem Compiler, dass der folgende Bezeichner ein Typ sein soll, notwendig (und i.d.R. nur dann zulässig) ist das, wenn du es mit einem abhängigen Bezeichner zu tun hast, also einem, dessen Bedeutung von Templateparametern abhängt oder abhängen könnte.



  • alles klar, jetzt hab ich verstanden, danke.


Anmelden zum Antworten