Ciao a tutti, sto leggendo una guida sul C++ e sono arrivato ai template. Per fare una prova, ho fatto questa classe:
dove ho scritto il + in modo inline, e il - in modo espanso (tutto corretto?)codice:template <int _N> class Zn { int _val; int _mod(int n){ return (n>=0) ? (n % _N) : (_N - ( (-n) % _N))%_N; } public: Zn(){ _val = 0; } Zn(int n){ _val = _mod(n); } Zn operator +(Zn b){ return Zn(_val + b._val); } Zn operator -(Zn b); int getN(){ return _N; } int getval(){ return _val; } }; template <int _N> Zn<_N> Zn<_N>::operator -(Zn<_N> b) { return Zn(_val - b._val); }
Ora, volevo aggiungere il << per stampare a video, ma dovendo fare una funzione friend, non ho idea della sintassi (che sul libro non c'è scritta in questo caso specifico).
Quello che avevo pensato "inventando a senso" era:
che però non compila, sembra che il <int _N> nel caso di una funzione membro viene preso quello della classe, nel caso di una funzione non membro viene "ridefinito", e infatti il compilatore mi segnala una duplicazione di _N... e allora ho modificato così:codice:template <int _N> class Zn { int _val; int _mod(int n){ return (n>=0) ? (n % _N) : (_N - ( (-n) % _N))%_N; } public: Zn(){ _val = 0; } Zn(int n){ _val = _mod(n); } Zn operator +(Zn b){ return Zn(_val + b._val); } Zn operator -(Zn b); int getN(){ return _N; } int getval(){ return _val; } template <int _N> friend ostream &operator <<(ostream &stream, Zn<_N> o); }; template <int _N> Zn<_N> Zn<_N>::operator -(Zn<_N> b) { return Zn(_val - b._val); } template <int _N> ostream &operator <<(ostream &stream, Zn<_N> o) { stream << o._val; return stream; }
e così funziona tutto. Ho inoltre anche aggiunto il + tra due classi diverse, facendo:codice:template <int _N> class Zn { int _val; int _mod(int n){ return (n>=0) ? (n % _N) : (_N - ( (-n) % _N))%_N; } public: Zn(){ _val = 0; } Zn(int n){ _val = _mod(n); } Zn operator +(Zn b){ return Zn(_val + b._val); } Zn operator -(Zn b); int getN(){ return _N; } int getval(){ return _val; } template <int __N> friend ostream &operator <<(ostream &stream, Zn<__N> o); }; template <int _N> Zn<_N> Zn<_N>::operator -(Zn<_N> b) { return Zn(_val - b._val); } template <int __N> ostream &operator <<(ostream &stream, Zn<__N> o) { stream << o._val; return stream; }
e anche questa cosa funziona.codice:#include <iostream> using namespace std; template <int _N> class Zn { int _val; int _mod(int n){ return (n>=0) ? (n % _N) : (_N - ( (-n) % _N))%_N; } public: Zn(){ _val = 0; } Zn(int n){ _val = _mod(n); } Zn operator +(Zn b){ return Zn(_val + b._val); } Zn operator -(Zn b); int getN(){ return _N; } int getval(){ return _val; } template <int __N> friend ostream &operator <<(ostream &stream, Zn<__N> o); template <int __N1, int __N2> friend Zn<__N1> operator +(Zn<__N1> o1, Zn<__N2> o2); }; template <int _N> Zn<_N> Zn<_N>::operator -(Zn<_N> b) { return Zn(_val - b._val); } template <int __N> ostream &operator <<(ostream &stream, Zn<__N> o) { stream << o._val; return stream; } template <int __N1, int __N2> Zn<__N1> operator +(Zn<__N1> o1, Zn<__N2> o2) { return Zn<__N1>(o1._val + o2._val); }
La mia domanda è: è giusto quello che ho scritto, visto che l'ho "inventato"? C'è un modo migliore?
Grazie!

Rispondi quotando