Une première possibilité consiste à définir un type spécial struct manip
par exemple, et de redéfinir les opérateurs pour ce type afin davoir leffet souhaité ; les manipulateurs seraient alors des constantes de ce type. malheureusement cela conduit à « fermer » le processus, en ce sens quil est alors impossible de définir de nouveaux manipulateurs.
Une méthode plus astucieuse est utilisée en réalité. Elle consiste à noter quil est parfaitement possible de passer un argument de type « pointeur sur fonction » à un opérateur. Voici donc par exemple comment sont implantés les manipulateurs endl
, ends
et flush
sur les flots de sorties :
class ostream : virtual public ios { // ... ostream& operator<< (ostream& (*f)(ostream&)) { return (*f)(*this); } // ... };ostream& endl(ostream& os){ os << '\n' // nouvelle ligne os.flush() // vider le tampon return *this;}ostream& ends(ostream& os){ os << '\0' // caractère nul return *this;}ostream& flush(ostream& os){ os.flush() // vider le tampon return *this;}
Les manipulateurs dec
, hex
et oct
agissent sur la classe ios
simplement en changeant le bit adéquat dans le champ de forme. Le manipulateur ws
agit sur istream
également en positionnant le bit adéquat. Il est tout à fait possible de définir ses propres manipulateurs sur ce modèle.
Les manipulateurs avec paramètres sont nettement plus complexes, mais le principe de base est le même. Il faut cependant utiliser une classe intermédiaire dans ce cas. Voici, en simplifiant, une implantation de setw
:
class smanip { ios& (*fn)(ios&, int); int ag; public: smanip(ios& (*f)(ios&, int), int a) { fn = f; ag = a; } friend istream& operator>>(istream& s, smanip& f) { (*f.fn)(s, f.ag); return s; } friend ostream& operator<<(ostream& s, smanip& f) { (*f.fn)(s, f.ag); return s; } };ios& setw_fonc(ios& io, int w){ io.width(w); return io;}smanip setw(int w){ return smanip(setw_fonc, w);}
Le comportement est en fait un peu plus complexe, et de plus le fichier <iomanip.h>
est rendu pratiquement illisible par lemploi de macros et de classes génériques.