Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

template et friend

8 réponses
Avatar
Cyril.Gruau
Comment assurer la portabilite, sachant que :

template<class T> classe MaClasse
{
public:
friend ostream & operator<<<>(ostream & OUT, const MaClasse<T> & A);
  friend istream & operator>><>(istream & IN, MaClasse<T> & A);
};

n'est pas accepte par tous les compilateurs (notamment cl.exe) ?

Cyril

8 réponses

Avatar
Cyril.Gruau
template<class T> class MaClasse
{
public:
template<class U> friend ostream & operator<<(ostream & OUT,
const MaClasse<U> & A);
  template<class U> friend istream & operator>>(istream & IN,
MaClasse<U> & A);
};

semble fonctionner

Cyril
Avatar
Christophe de Vienne
Cyril Gruau wrote:

Comment assurer la portabilite, sachant que :

template<class T> classe MaClasse
{
public:
friend ostream & operator<<<>(ostream & OUT, const MaClasse<T> & A);
friend istream & operator>><>(istream & IN, MaClasse<T> & A);
};

n'est pas accepte par tous les compilateurs (notamment cl.exe) ?

Cyril


Ce que je ferais plutot, c'est de ne pas mettre les opérateurs en friend, et
déclarer une fonction MaClasse<>::print(ostream &), que tu appelles dans
l'opérateur :

template<class T>
ostream & operator<<(ostream & o, const MaClasse<T> & a)
{
a.print(o);
return o;
}

J'imagine que plus de compilateurs l'accepterons.

A+

Christophe

--
Christophe de Vienne
Experience is something you don't get until just after you need it.
Oliver's Law.

Avatar
Cyril.Gruau
Ce que je ferais plutot, c'est de ne pas mettre les opérateurs en friend, et
déclarer une fonction MaClasse<>::print(ostream &), que tu appelles dans
l'opérateur :

template<class T>
ostream & operator<<(ostream & o, const MaClasse<T> & a)
{
a.print(o);
return o;
}

J'imagine que plus de compilateurs l'accepterons.


Vrai, mais si je peux eviter de transferer les corps de tous mes
fonctions amies dans des methodes membres ...

Cyril

Avatar
Cyril.Gruau
template<class T> class MaClasse
{
public:
template<class U> friend ostream & operator<<(ostream & OUT,
const MaClasse<U> & A);
  template<class U> friend istream & operator>>(istream & IN,
MaClasse<U> & A);
};

semble fonctionner


Faux, car ensuite cl.exe n'accepte ni

template<class U> friend ostream & operator<<(ostream & OUT,
const MaClasse<U> & A)
{
U temporaire;
...
}

ni

template<class T> friend ostream & operator<<(ostream & OUT,
const MaClasse<T> & A)
{
T temporaire;
...
}

-> impasse.

Cyril

Avatar
Christophe Lephay
"Cyril Gruau" a écrit dans le message de
news:
Ce que je ferais plutot, c'est de ne pas mettre les opérateurs en friend,
et


déclarer une fonction MaClasse<>::print(ostream &), que tu appelles dans
l'opérateur :

template<class T>
ostream & operator<<(ostream & o, const MaClasse<T> & a)
{
a.print(o);
return o;
}

J'imagine que plus de compilateurs l'accepterons.


Vrai, mais si je peux eviter de transferer les corps de tous mes
fonctions amies dans des methodes membres ...


Celà permet pourtant un comportement polymorphe...

Chris


Avatar
Jean-Marc Bourguet
(Cyril Gruau) writes:

Comment assurer la portabilite, sachant que :

template<class T> classe MaClasse
{
public:
friend ostream & operator<<<>(ostream & OUT, const MaClasse<T> & A);
  friend istream & operator>><>(istream & IN, MaClasse<T> & A);
};

n'est pas accepte par tous les compilateurs (notamment cl.exe) ?


Tu veux dire que

class istream;
class ostream;
ostream& operator<<(ostream&, int);
istream& operator>>(istream&, int&);

template<class T> class MaClasse;

template<class T>
ostream& operator<<(ostream&, MaClasse<T> const&);
template<class T>
istream& operator>>(istream&, MaClasse<T> const&);

template<class T> class MaClasse
{
public:
friend ostream& operator<< <>(ostream&, MaClasse<T> const&);
friend istream& operator>> <>(istream&, MaClasse<T>&);
private:
int x;
};

template<class T>
ostream& operator<<(ostream& os, MaClasse<T> const& c)
{
os << c.x;
return os;
}

template<class T>
istream& operator>>(istream& is, MaClasse<T> const& c)
{
is >> c.x;
return is;
}

n'est pas accepté? C'est quoi les erreurs?

(C'est volontairement que je déclare istream et ostream comme ça pour
éviter des problèmes éventuels avec les namespaces).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Cyril.Gruau
Tu veux dire que

class istream;
class ostream;
ostream& operator<<(ostream&, int);
istream& operator>>(istream&, int&);

template<class T> class MaClasse;

template<class T>
ostream& operator<<(ostream&, MaClasse<T> const&);
template<class T>
istream& operator>>(istream&, MaClasse<T> const&);

template<class T> class MaClasse
{
public:
friend ostream& operator<< <>(ostream&, MaClasse<T> const&);
friend istream& operator>> <>(istream&, MaClasse<T>&);
private:
int x;
};

template<class T>
ostream& operator<<(ostream& os, MaClasse<T> const& c)
{
os << c.x;
return os;
}

template<class T>
istream& operator>>(istream& is, MaClasse<T> const& c)
{
is >> c.x;
return is;
}

n'est pas accepté? C'est quoi les erreurs?


Tout simplement

syntax error : missing ';' before '<'

sur la ligne

friend ostream& operator<< <>(ostream&, MaClasse<T> const&);


a cause du <>

Cyril

Avatar
Cyril.Gruau
Celà permet pourtant un comportement polymorphe...


Et de fait, je reconnais que c'est la seule solution qui fonctionne
bien (ceci-dit, il me reste encore quelques compilateurs a tester).

Cyril