Komposition von Template-Klassen



  • Hi,
    folgendes Codestück bereitet mir Sorgen:

    template <typename T>
    class scalar {
    	public:
    		typedef T value_type;
    
    		scalar(value_type const& t)
    			: value_(t) {}
    
    		value_type& operator()() {
    			return value_;
    		}
    
    	private:
    		value_type value_;
    };
    
    template <typename T>
    class expr {
    	public:
    		typedef T expr_type;
    
    		expr(expr_type const& t)
    	   		: expr_(t) {}
    
    		expr_type& operator()() {
    			return expr_();
    		}
    
    	private:
    		expr_type& expr_;
    };
    
    int main() {
    	scalar<int> s(2);
    	expr<scalar<int> > e(s);	
    	return 0;
    }
    

    Fehlermeldung:

    expr_templ.cpp: In constructor ‘expr<T>::expr(const T&) [with T = scalar<int>]’:
    expr_templ.cpp:35:   instantiated from here
    expr_templ.cpp:23: error: invalid initialization of reference of type ‘scalar<int>&’ from expression of type ‘const scalar<int>’
    

    Im Endeffekt soll das Erstellen eines Expressiontrees möglich sein.
    Woran scheitert es hier?

    mfg und guten Rutsch



  • template <typename T> class scalar 
    {
        public:
            typedef T value_type;
            scalar(value_type const& t) : value_(t) {}
            value_type& operator()() { return value_; }
        private:
            value_type value_;
    };
    
    template <typename T> class expr 
    {
        public:
            typedef T expr_type;
            expr(expr_type &t) : expr_(t) {}
            expr_type& operator()() { return expr_(); }
        private:
            expr_type& expr_;
    };
    
    int main() 
    {
        scalar<int> s(2);
        expr< scalar<int> > e(s);  
    }
    


  • hmpf, danke



  • Wenn der Expression-Tree nur lesend auf die Daten zugreifen soll, dann kannst du auch beidesmal 'const' benutzen.
    - scalar

    const value_type& operator()() { return value_; }
    

    - expr

    expr(const expr_type &t) : expr_(t) {}
    const expr_type& operator()() { return expr_(); }
    private: 
      const expr_type& expr_;
    

    Auch sollten die operator()-Methoden selbst als const deklariert sein:

    const expr_type& operator()() const { return expr_(); }
    


  • Hi zeronull,

    mal ein kleiner Tipp von mir: Fehler findet man schneller, wenn man weiter reduziert (hast Du bestimmt schon gemacht) - am Besten erstmal "un-template-isiert":

    class expr {
    public:
        expr(int const& t) : expr_(t) {}
    private:
        int& expr_;
    };
    

    Das hier läuft nämlich schon auf denselben Fehler ... und da ist vielleicht auch klarer, warum der Compiler eine non-const Referenz nicht an eine const-Referenz binden will. 😃

    Mein Arbeitskollege hantiert auch viel mit templates herum ... und in 90% der Fälle hat der Fehler nichts damit zu tun, dass es templates sind. Daher immer meine erste Frage: "Läuft's denn mit der konkreten Klasse/Funktion ?".

    Gruß,

    Simon2.


Anmelden zum Antworten