Newsgroup: it.comp.lang.c++
Titolo: Friend, template e operator<<

Cia a tutti,
come faccio a dichiarare friend ad una classe template l'operatore
operator<<?
Mi spiego:
tmplate<class A>
class B
{
	A pippo;
 
	friend ostream& operator<<(ostream& os, B<A>& p);
 public:
	B(void);
	~B(void);
};
tmplate<class A>
friend ostream& operator<<(ostream& os, B<A>& p)
{
	/*   */
}
co Dev-C++ e quindi Mingw.
Grazie a tutti.
Stefano
stsTO...@freemail.it
 (occhio all'antispam)

 a écrit dans le message news:
e1f3buoquh7poioml...@4ax.com...

Ciao,
ti rispondo postandoti un codice che ti interessera'.
In particolare il problema dell'operatore << che ha per argomento un
template generico, lo risolvi implementando l'operatore << che avra' per
argomento l'istanziazione del template con il tipo che stai utilizzando.
Ovvero, nel template metti la dichiarazione:
friend ostream& operator<<(ostream& os, const matrix<R>& m);
e poi fuori dal template definisci quella che ti serve, ovvero quella col
tipo double al posto di R:
ostream& operator<<(ostream& os, const matrix<double>&m)
Ti posto il codice completo:
#define NOMEM 100
#define OUTOFLIMITS 200
#include <iostream>
#ifdef WIN32
#include <conio.h>
#endif
using namespace std;
typedef int indice;
template<class R>
class matrix
{
    private:
        R *mat;
        unsigned nr, nc;
        void allocator(unsigned r, unsigned c);
        void deallocator(void);
    public:
        matrix();
// copy constructor
        matrix(const matrix<R>& m)
           if (&m != NULL)
              {mat = NULL; allocator(
m.nr
, 
m.nc
);}};
 // constructor  rect matrix (r, c)
        matrix(unsigned r, unsigned c) {mat = NULL; allocator(r, c);};
// constructor quad matrix (n, n)
        matrix(unsigned n) {mat = NULL; allocator(n,n);};
        ~matrix();
        R& operator()(unsigned r, unsigned c) const;
        const matrix<R>& operator=(const matrix<R> &rhv);
        void set(const R &d);
        friend ostream& operator<<(ostream& os, const matrix<R>& m);
};
ostream& operator<<(ostream& os, const matrix<double>&m)
{
    indice r, c;
    os << " (" << 
m.nr
 << "," << 
m.nc
<< ")" << ' ' << endl;
    for(r=0;r<
m.nr
;r++)
    {
        for(c=0;c<
m.nc
;c++)
        {
            os << (m)(r,c);
   os << ' ';
        }
        os << endl;
    }
    return os;
};
template<class R>
void matrix<R>::allocator(unsigned r, unsigned c)
{
    if(mat!=NULL)
        deallocator();
    mat = (R*)new R[r*c];
    if(mat == NULL)
        exit(NOMEM);
    nr=r;
    nc=c;
    set(0.0);
}
template<class R>
void matrix<R>::deallocator(void)
{
    delete[] mat;
    mat = NULL;
    nr = nc =0;
}
template<class R>
matrix<R>::matrix()
{
    mat = NULL;
    nr = nc = 0;
}
template<class R>
matrix<R>::~matrix()
{
    deallocator();
}
template<class R>
void matrix<R>::set(const R &d)
{
    unsigned r, c;
    for(r=0;r<nr;r++)
        for(c=0;c<nc;c++)
            (*this)(r,c)=d;
}
template<class R>
R& matrix<R>::operator()(unsigned r, unsigned c) const
{
    if(r<0 || r>=nr || c<0 || c>=nc)
        exit(OUTOFLIMITS);
    return mat[nc*r+c];
}
template<class R>
const matrix<R>& matrix<R>::operator=(const matrix<R> &rhv)
{
    if(this == &rhv)
  return *this;
    if (
rhv.nr
 != nr || 
rhv.nc
 != nc)
  return rhv;
    unsigned r, c;
    for(r=0; r < nr; r++)
        for(c=0; c < nc; c++)
            (*this)(r,c) = rhv(r, c);
 return *this;
}
int main()
{
 matrix<double> m(20,10);
 matrix<double> m2(m);
 matrix<double> m3(20,10);
 m3.set(5.6);
 cout << m;
 m = m2 = m3;
 cout << m;
 cout << m2;
#ifdef WIN32
 getch();
#endif
 return 0;
}
Maurus