operator<< & >> in template klasse



  • #include <iostream>
    
    template<typename T>
    class base {
    protected:
    	T b;
    	friend std::ostream& operator<<(std::ostream& os, const base<T>& bs);
    	virtual void print(std::ostream& os) const;
    public:
    	void set(int s) { b = s; };
    	void a(const base& c) { b = c.b; };
    	int get() { return b; };
    };
    
    template<typename T>
    std::ostream& operator<<(std::ostream& os, const base<T>& bs) {
    	bs.print(os);
    	return os;
    };
    
    template<typename T>
    void base<T>::print(std::ostream& os) const {
    	os << this->b;
    };
    
    class derived: public base<int> {
    public:
    	derived() {};
    	derived(int d) { this->b = d; };
    };
    
    int main() {
    	derived b, e;
    	e.set(100);
    	b.a(e);
    	std::cout << e << std::endl;
    	std::cout << b << std::endl;
    	system("pause");
    }
    

    hier bekomme ich link fehler 2001

    Error 1 error LNK2001: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class base<int> const &)" (??6@YAAAV?basic_ostream@DU?basic\_ostream@DU?char_traits@D@std@@@std@@AAV01@ABV?$base@H@@@Z) main.obj Testcode

    noch eine Frage, hab irgendwo gelesen, dass konstruktoren und zuweisungsoperator nicht automatische vererbt werden, is das korrekt? bitte um bestaetigung, danke sehr



  • Konstruktoren, Destruktoren, Zuweisungsoperatoren, und friends werden nicht vererbt.



  • hab eben so geaendert trotz bekomme ich link fehler.

    int main() {
        base<int> b, e;
        e.set(100);
        b.a(e);
        std::cout << e << std::endl;
        std::cout << b << std::endl;
        system("pause");
    }
    


  • protected ist nach aussen, wie private . Du musst die Schnittstellte public machen. Sonst ist die Funktion nicht erreichbar.



  • friend std::ostream& operator<<(std::ostream& os, const base<T>& bs);
    

    Das deklariert bei dir eine einzige Funktion. Das ist keine Templatefunktion.

    template<typename T>
    std::ostream& operator<<(std::ostream& os, const base<T>& bs) {
        bs.print(os);
        return os;
    };
    

    Hier definierst du eine Templatefunktion. Die hat nichts mit der ersten zu tun. Mögliche Lösungen: Definition schon in die Klasse schreiben, oder friend weglassen und die print-Funktion öffentlich zugänglich machen, oder

    template<typename U>
    friend std::ostream& operator<<(std::ostream& os, const base<U>& bs);
    

    In der Klasse schreiben.



  • template<typename T>  
    class IOStreamOut;  
    
    template<typename T>  
    std::ostream& operator<<(std::ostream& os, const IOStreamOut<T>& obj)
    {
        std::string buffer = obj.Get().ToString();
        os.write( buffer.c_str(), static_cast<std::streamsize>(buffer.size()) );
        return os;
    }
    
    template<typename T>
    class IOStreamOut 
    {
    public:
    
        /*
        * C'tor
        */
        IOStreamOut( const T& obj )
            : m_obj( obj )
        {
        }
    
        /*
         * D'tor
         */
        virtual ~IOStreamOut(){};
    
        /*
         * ostream operator
         */
        friend std::ostream &operator<< <>(std::ostream &, const IOStreamOut<T>& obj);  
    
        /*
         * Get the wrapped object
         */
        T Get() const
        {
            return m_obj;
        }
    
    private:
    
        /*
         * C'tor
         *
         * Default constructor should never be called.
         */
        IOStreamOut(){};
    
        /*
         * The wrapped object
         */
        T m_obj;
    
    };
    

    hier is die gute loesung
    danke trotzdem eure hilfe



  • ohne den rest gesehen zu haben:

    os.write( buffer.c_str(), static_cast<std::streamsize>(buffer.size()) );
    

    Oo

    os << buffer;
    

    ist wohl zu einfach?

    und das hier zu kurz?

    template<typename T>  
    std::ostream& operator<<(std::ostream& os, const IOStreamOut<T>& obj)
    {
        return os << obj.Get().ToString();
    }
    

    bb



  • #include <iostream>
    
    template<typename T> class base;
    template<typename T> std::ostream& operator<<(std::ostream& os, const base<T>& bs);
    template<typename T> std::ostream& operator>>(std::istream& is, base<T>& bs);
    class derived;
    
    template<typename T>
    class base {
    protected:
        T b;
        friend std::ostream& operator<< <>(std::ostream& os, const base<T>& bs);
        friend std::ostream& operator<< <>(std::istream& is, base<T>& bs);
        virtual void print(std::ostream& os) const;
        virtual void getinput(std::istream& is);
    public:
        void set(int s) { b = s; };
        void a(const base& c) { b = c.b; };
        int get() { return b; };
    };
    
    template<typename T>
    std::ostream& operator<<(std::ostream& os, const base<T>& bs) {
        bs.print(os);
        return os;
    };
    
    template<typename T>
    std::ostream& operator<<(std::istream& is, base<T>& bs) {
        bs.getinput(is);
        return is;
    };
    
    template<typename T>
    void base<T>::print(std::ostream& os) const {
        os << this->b;
    };
    
    template<typename T>
    void base<T>::print(std::istream& is) {
        os >> this->b;
    };
    
    int main() {
        base<char> b = 'A';
        std::cout << e << std::endl;
        std::cout << b << std::endl;
        system("pause");
    }
    

    also ich hab ausprobiert, bei Zahlentypen, ab unsigned short bis long long, funktioniert operator>> ohne problem, also base<WORD>, base<int>, base<long> kein problem, nur bei base<char> und base<wchar_t> weigert er die kompiliertarbeit, folgende fehler spuck es aus

    Error 2 error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion) Testcode

    wie aendere ich es, dass es funktioniert, hab kein idee momentan



  • Du hast da ein paar schräge Fehler, vermutlich Copy&Paste. Schau nochmal genau alle op<</>> und i/ostream an 😉



  • KasF schrieb:

    Du hast da ein paar schräge Fehler, vermutlich Copy&Paste. Schau nochmal genau alle op<</>> und i/ostream an 😉

    jo, hast recht, hier nun ohne copy fehler, kompilierfehler immer noch das selbe

    #include <iostream>
    template<typename T> class base;
    template<typename T> std::ostream& operator<<(std::ostream& os, const base<T>& bs);
    template<typename T> std::istream& operator>>(std::istream& is, base<T>& bs);
    
    template<typename T>
    class base {
    protected:
    	T b;
    	friend std::ostream& operator<< <>(std::ostream& os, const base<T>& bs);
    	friend std::istream& operator>> <>(std::istream& is, base<T>& bs);
    	virtual void print(std::ostream& os) const;
    public:
    	base(const T& a): b(a) {};
    	void set(int s) { b = s; };
    	void a(const base& c) { b = c.b; };
    	int get() { return b; };
    };
    
    template<typename T>
    std::ostream& operator<<(std::ostream& os, const base<T>& bs) {
    	os << bs.b;
    	return os;
    };
    
    template<typename T>
    std::istream& operator>>(std::istream& is, base<T>& bs) {
    	is >> bs;
            return is;
    }
    
    template<typename T>
    void base<T>::print(std::ostream& os) const {
    	os << this->b;
    };
    
    class derived: public base<char> {
    public:
    	derived(char d):base(d) {  };
    };
    
    int main() {
    	base<char> b = 'A';
    	std::cin >> b >> std::endl;
    	std::cout << b << std::endl;
    	system("pause");
    }
    

Anmelden zum Antworten