[C++] overload dell'operatore con template di classe

di il
3 risposte

[C++] overload dell'operatore con template di classe

Buonasera,
devo fare un esercizio del manuale c++ su cui sto studiando, mi chiede di creare un template per una classe creata in un esercizio precedente.
La classe prevede la ridefinizione di tutti gli operatori, quelli aritmetici e quelli di confronto.
La classe singola funziona bene, quando però ho fatto il template il compilatore sono arrivati i problemi.... perche nel programma di verifica non riesco a gestire 2 istanze di classe per tipi diversi.... mi da errore subito senza via di scampo
Sotto riporto la versione semplificata del template di classe che ho rifatto, per semplicità, con solo l'overload dell'operatore ==

E' 3 giorni che mi spacco il cervello.... qualche anima pia che mi spiega dove erro e come risolvere???

intestazione.h

#include<iostream>

template<class T, int MAX>
class Elenco
{
public:
	Elenco();
	~Elenco();
	void stampa();
	bool operator==(const Elenco<T, MAX>&) const;
	
	private:
	int elementi;
	T *ptr;
};
origine.cpp

#include"Intestazione.h"
#include<iostream>
#include<ctime>
using namespace std;

	template<class T, int MAX>
	Elenco<T, MAX>::Elenco()
	{
		elementi = MAX;
		ptr = new T[MAX];
	
		for (int i = 0; i < elementi; i++)
		{
			ptr[i] = rand() % 100;
		}
	}

	template<class T, int MAX>
	Elenco<T, MAX>::~Elenco()
	{
		delete[] ptr;
	}

	template<class T, int MAX>
	void Elenco<T, MAX>::stampa()
	{
		for (int i = 0; i < elementi; i++)
		{
			cout << ptr[i] << " ";
			if ((i + 1) % 4 == 0) cout << endl;
		}
		cout << "\nfine";
	}
	
	

	template<class T, int MAX>
	bool Elenco<T, MAX>::operator==(const Elenco<T, MAX > &right) const
	{
		if (sizeof (*this) == sizeof (right)) return true;
		else return false;
	}



int main()
{
	srand((unsigned int)time(0));

	Elenco<char, 10> elenco1;
	Elenco<int, 10> elenco2;
	Elenco<int, 11>elenco3;
	
	

	elenco2.stampa();
	cout << endl<<endl;
	elenco3.stampa();

	cout << endl<<"i template sono di tipo ";
	if (elenco2 == elenco3) cout << "uguale";	//QUI HO L'ERRORE SUL CONFRONTO DI ISTANZA DI TIPO DIVERSO
	else cout << "diverso";
	
	cout << endl << "i template sono di tipo ";
	if (elenco1 == elenco2) cout << "uguale";	/QUI HO L'ERRORE SUL CONFRONTO DI ISTANZA DI TIPO DIVERSO
	else cout << "diverso";


	cout << endl << endl;
	return 0;
}
Quando vado a compilare mi da questi errori nel file origine.cpp

Errore C2678 '==' binario: non è stato trovato alcun operatore che accetti un operando sinistro di tipo 'Elenco<int,10>'. È anche possibile che non vi siano conversioni accettabili. Project1 d:\sandro\documenti\c++\esercizi libro\cap 1 template\prove\template di classe\project1\origine.cpp

Errore (attivo) E0349 nessun operatore "==" corrispondente agli operandi Project1 D:\Sandro\Documenti\C++\esercizi libro\cap 1 template\prove\template di classe\Project1\Origine.cpp

3 Risposte

  • Re: [C++] overload dell'operatore con template di classe

    Ciao, volendo riprodurre lo stesso errore semplificando ulteriormente il codice, potremmo considerare qualcosa del genere:
    #include <iostream>
    
    using namespace std;
    
    template<class T>
    class A
    {
    public:
    	bool operator ==(const A<T>&)const;
    
    private:
    	T data;
    };
    
    template<class T>
    bool A<T>::operator ==(const A<T> &right)const
    {
        return(sizeof(*this) == sizeof(right));
    }
    
    int main()
    {
    	A<char> c1;
    	A<double> c2;
    	cout << (c1 == c2);
    }
    
    Ovviamente l'overload dell'operatore == si aspetta un argomento dello stesso tipo dell'oggetto con cui hai richiamato il metodo, da cui l'errore...
    Se invece l'argomento right deve poter essere anche di tipo diverso, basta semplicemente dichiarare un metodo template:
    #include <iostream>
    
    using namespace std;
    
    template<class T>
    class A
    {
    public:
        template<class W>
        bool operator ==(const A<W>&)const;
    
    private:
    	T data;
    };
    
    template<class T>
    template<class W>
    bool A<T>::operator ==(const A<W> &right)const
    {
        return(sizeof(*this) == sizeof(right));
    }
    
    int main()
    {
    	A<char> c1;
    	A<double> c2;
    	cout << (c1 == c2);
    }
    
    Da notare anche come l'overload di == possa essere scritto in maniera più compatta.

    P.S.
    Nei tuoi intenti quando due elenchi sono da considerarsi uguali?
  • Re: [C++] overload dell'operatore con template di classe

    Grazie della risposta....ho capito il punto ed ora funziona.
    Ho anche migliorato il confronto di tipo perche al posto di sizeof(*this)==sizeof(right) ho messo sizeof(T)==sizeof(W).

    Nel caso dell'esempio due elenchi sono uguali quando il tipo, numero elementi e valore elementi è uguale. Non riuscendo a verificare l'uguaglianza dei tipi non potevo andare avanti... ho messo un paio di if per verifica di tipo e numero elementi, poi un ciclo di while per la verifica del valore degli elementi.

    secondo te il controllo del tipo è corretta verificandone la dimensione con sizeof? oppure c'è un metodo migliore?
  • Re: [C++] overload dell'operatore con template di classe

    Https://en.cppreference.com/w/cpp/types/is_sam
Devi accedere o registrarti per scrivere nel forum
3 risposte