Pages

lundi 27 août 2012

Bien surcharger les flux

La surcharge de flux se fait avec les opérateurs << et >>, avec respectivement les classes std::basic_ostream<_CharT, _Traits> et std::basic_istream<_CharT, _Traits>.
Leurs définitions -ainsi que tous les types de flux et buffers de la std- se trouvent dans <iosfwd> (pour ios forward, voir le billet précédent ;)). Inutile d'inclure <ostream> ou <istream> et encore moins <iostream>.

Sur le web beaucoup d'exemples se basent uniquement sur std::ostream et std::istream, mais ce ne sont en fait que des alias.

typedef basic_istream<char> istream;
typedef basic_ostream<char> ostream;

Les exemples montrés avec ces 2 types ne fonctionnent pas lorsque par exemple un std::wcout est utilisé (flux de sortie standard de type wostream = basic_ostream<wchar_t>).

Pour un maximum de compatibilité, il faut utiliser les classes de bases, ce qui donne :

#include <iosfwd>

template<typename _CharT, typename _Traits>
std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& os, const MyType& a)
{
 return os << ...;
}

template<typename _CharT, typename _Traits>
std::basic_istream<_CharT, _Traits>&
operator>>(std::basic_istream<_CharT, _Traits>& is, MyType& a)
{
 return is >> ...;
}

Dans certaines circonstances, le flux devrait avoir un accès aux membres privés, il faudra donc en faire une fonction amie.

class MyType
{
 //...
 template<typename _CharT, typename _Traits>
 friend std::basic_ostream<_CharT, _Traits>&
 operator<<(std::basic_ostream<_CharT, _Traits>& os, const MyType& a);
};

Aucun commentaire: