Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    [C++] Overload operatore output/input (<<, >>) per template

    Windows 7 - Visual Studio 2010

    Qual'è la corretta implementazione dell'overloading per gli stream operator << e >> per una class templates?

    Esempio:

    codice:
    template <typename T>
    class myClass
    {
    	// Overloading dell'operatore di output <<
    	friend ostream & operator<<( ostream &output, const myClass &right );
    
    	// Overloading dell'operatore di input >>
    	friend istream & operator>>( istream &input, myClass &right );
    };

    Il problema è che cercando di implementarle nel .h ottengo errori di linker. Qual'è la soluzione corretta?

    Inoltre perchè per i compilatore non cè differenza tra una dichiarazione del tipo:

    codice:
    template <typename T>
    class myClass
    {
    	void funct( myClass &obj );
    };
    Ed una dichiarazione del tipo:
    codice:
    template <typename T>
    class myClass
    {
    	void funct( myClass<T> &obj );
    };
    Qual'è la forma corretta? E perchè?

    Grazie.
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Ci sono due soluzioni per fare quello che chiedi:
    il primo ( e più usato ) è:
    codice:
    template <typename T>
    class myClass
    {
    	// Overloading dell'operatore di output <<
    	friend ostream & operator<<( ostream &output, const myClass &right ) {
                output<< right.membro_privato;
                /* altro */
                return output;
            }
    
    	// Overloading dell'operatore di input >>
    	friend istream & operator>>( istream &input, myClass &right ) {
                input >> right.membro_privato;
                /* altro */
                return input ;
            }
    };
    il secondo più lungo ( e usato meno):
    codice:
    template <typename T>
    class myClass;
    
    template <typename T>
    ostream & operator<<( ostream &output, const myClass<T> &right );
    
    template <typename T>
    istream & operator>>( istream &input, myClass<T> &right );
    
    template <typename T>
    class myClass
    {
    	// Overloading dell'operatore di output <<
    	friend ostream & operator<<  <>( ostream &output, const myClass &right );
    
    	// Overloading dell'operatore di input >>
    	friend istream & operator>> <>( istream &input, myClass &right );
    };
    
    
    template <typename T>
    ostream & operator<<( ostream &output, const myClass<T> &right ) {
        output<< right.membro_privato;
        /* altro */
        return output;
     }
    
    // Overloading dell'operatore di input >>
    template <typename T>
    istream & operator>>( istream &input, myClass<T> &right ) {
        input >> right.membro_privato;
        /* altro */
        return input ;
    }
    Qual'è la forma corretta?
    Tutte e due, anche se la seconda è pleonastica e non si usa.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    Grazie avevo appunto verificato che la prima forma di implementazione non dava problemi, ma la tua risposta ha saziato le mie richieste.
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  4. #4
    Qual'è il modo migliore per riconoscere il tipo di T run-time all'interno di queste funzioni?
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  5. #5
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    A run time lo puoi sapere usando typeid;
    codice:
    #include <typeinfo>
    ...
    
    template <class T>
    class Pippo {
    	public:
    		typedef T value_type;
    
    };
    
    ... 
    
    int main() {
        cout << (typeid(Pippo<int>::value_type) == typeid(int) ) << endl; 
        cout << typeid(Pippo<int>::value_type).name() << endl; 
    }
    La funzione .name() restituisce una stringa implementation defined, che non so quanto possa essere utile.

    Se però il tipo T è possibile determinarlo a compile time, si possono usare i type_traits o crearsene uno specifico. Dipende da cosa ti serve.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  6. #6
    Si ero a conoscenza di typeid , speravo ci fosse un altro metodo, per ora userò questo.

    Venendo alla prima implementazione l'ho dovuta scrivere necessariamente nella forma seguente (perchè senza il <T> di cui discutevamo prima il compilatore dava errori in questo caso):

    codice:
    template <typename T>
    friend ostream & operator<<( ostream &output, const myClass<T> &right )
    {
    	// Altro
    
    	return output;
    }

    Il problema adesso si verifica quando ad esempio nel client dichiaro più di un oggetto di tipo myClass. In particolare mi da il seguente messaggio di errore:

    error C2995: 'std:stream &operator <<(std:stream &,const myClass<T> & )': modello di funzione già definito

    Perchè? E come risolvere il problema?


    Mentre senza il:

    codice:
    template <typename T>
    Sopra la dichiarazione della funzione questo problema non sussiste, tuttavia il compilatore si comporta in modo strano, ovvero (trattandosi di VS 2010) mi segna come errore (sottolineatura rossa e passandoci sopra con il cursore indica chiaramente qual'è il tipo di errore), ad esempio il fatto di aver dichiarato all'interno della funzione un oggetto di tipo T, o di voler accedere ad una variabile privata dello stesso oggetto, ma mi fa compilare lo stesso con 0 errori e 0 warning
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  7. #7
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Se metti template <typename T>, crei una template function e il compilatore si ritrova con due definizioni della stessa funzione.
    http://msdn.microsoft.com/en-us/libr...8VS.80%29.aspx

    tuttavia il compilatore si comporta in modo strano
    Facci l'abitudine. L'IDE non è perfetto e a volte s'inceppa ( a me capita con l'intellisense). L'importante è che il codice compili e stampi quanto richiesto.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.