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

Plusieurs formats d'affichage

7 réponses
Avatar
Marc Boyer
Bonjour,

je voudrais permettre à un objet d'être affiché (enfin,
envoyé dans un ostream quoi) suivant plusieurs formats
(un peu comme les hex, dec pour les nombres), et je me
demande quel est l'idiome.

Imaginons que mon objet obj puisse avoir deux formats de
sortie: tiny et large.

Difficile d'aller modifier std::cout pour qu'il accepte
cout<<tiny ou cout.setf(tiny).

D'un autre côté, l'idée de faire
obj.setf(tiny);
cout<<obj;
me dérange un rien car il faut que je stoque dans obj une information
d'affichage (ça peut se faire avec un mutable, mais bon...)

J'avais pensé à définir des classes tinyObjOstream et largeObjOstream
qui hériteraient de ostream, mais je suis pas sur que ostream se
laisse hériter gentillement.

Je pourrais aussi avoir une méthode inTinyFormat qui retournerait
un type spécifique ce qui permettrait d'écrire
cout<<obj.inTinyFormat();

Mais bon, j'imagine que c'est un idiome classique.


Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

7 réponses

Avatar
Samuel Krempp
le Friday 17 October 2003 11:54, écrivit :

Difficile d'aller modifier std::cout pour qu'il accepte
cout<<tiny


ça c'est faisable, le manipulateur peut ajouter des paramètres custom dans
le stream (pword et iword).
Mais c'est pas forcément le mieux.

Je pourrais aussi avoir une méthode inTinyFormat qui retournerait
un type spécifique ce qui permettrait d'écrire
cout<<obj.inTinyFormat();


oui, ou dans l'autre sens, faire des sur-types qui servent juste à indiquer
le formattage, c'est courant, et appeler le constructeur (ou un helper qui
créé) :
cout << TinyFormat(obj);

c'est un poil plus joli.

--
Sam

Avatar
Marc Boyer
Samuel Krempp wrote:
le Friday 17 October 2003 11:54, écrivit :
Difficile d'aller modifier std::cout pour qu'il accepte
cout<<tiny


ça c'est faisable, le manipulateur peut ajouter des paramètres custom dans
le stream (pword et iword).
Mais c'est pas forcément le mieux.


Je vais regarder ça.

Je pourrais aussi avoir une méthode inTinyFormat qui retournerait
un type spécifique ce qui permettrait d'écrire
cout<<obj.inTinyFormat();


oui, ou dans l'autre sens, faire des sur-types qui servent juste à indiquer
le formattage, c'est courant, et appeler le constructeur (ou un helper qui
créé) :
cout << TinyFormat(obj);

c'est un poil plus joli.


Question de gout surement, mais quand je vois constructeur,
j'ai tendance à penser "nouvel objet", avec construction/destruction
(et les questions de perfs associées) alors que c'est plus une
enveloppe en fait.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(


Avatar
Christophe de Vienne
Marc Boyer wrote:

Samuel Krempp wrote:

oui, ou dans l'autre sens, faire des sur-types qui servent juste à
indiquer le formattage, c'est courant, et appeler le constructeur (ou un
helper qui créé) :
cout << TinyFormat(obj);

c'est un poil plus joli.


Question de gout surement, mais quand je vois constructeur,
j'ai tendance à penser "nouvel objet", avec construction/destruction
(et les questions de perfs associées)


Mais que représente l'instanciation d'un objet à priori 'léger' (TinyFormat
contiendra juste un pointeur vers l'objet à afficher) sur la pile, comparé
à l'envoi de données vers un flux ?

C'est surement négligeable, surtout si les fonctions du helper sont inlinée
par le compilo.

A+

Christophe


Avatar
Marc Boyer
Christophe de Vienne wrote:
Marc Boyer wrote:

Samuel Krempp wrote:

oui, ou dans l'autre sens, faire des sur-types qui servent juste à
indiquer le formattage, c'est courant, et appeler le constructeur (ou un
helper qui créé) :
cout << TinyFormat(obj);

c'est un poil plus joli.


Question de gout surement, mais quand je vois constructeur,
j'ai tendance à penser "nouvel objet", avec construction/destruction
(et les questions de perfs associées)


Mais que représente l'instanciation d'un objet à priori 'léger' (TinyFormat
contiendra juste un pointeur vers l'objet à afficher) sur la pile, comparé
à l'envoi de données vers un flux ?

C'est surement négligeable, surtout si les fonctions du helper sont inlinée
par le compilo.


C'est non seulement négligeable mais en plus équivalent avec
l'autre propositions.
Je parlais juste d'a priori de style, de gout, aucune différence
objective entre les deux écritures.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(



Avatar
kanze
Marc Boyer wrote in message
news:<bmoe8v$4gg$...

je voudrais permettre à un objet d'être affiché (enfin, envoyé dans un
ostream quoi) suivant plusieurs formats (un peu comme les hex, dec
pour les nombres), et je me demande quel est l'idiome.

Imaginons que mon objet obj puisse avoir deux formats de sortie: tiny
et large.


Seulement deux ? Et à quoi sert std::ios_base::width().

Difficile d'aller modifier std::cout pour qu'il accepte
cout<<tiny ou cout.setf(tiny).


Pour que ça marche avec setf, en effet. Mais il n'y a pas de problème
pour en créer un manipulateur. Jette un coup oeil à côté de
ios_base::xalloc, ios_base::iword et ios_base::pword.

D'un autre côté, l'idée de faire
obj.setf(tiny);
cout<<obj;
me dérange un rien car il faut que je stoque dans obj une information
d'affichage (ça peut se faire avec un mutable, mais bon...)

J'avais pensé à définir des classes tinyObjOstream et largeObjOstream
qui hériteraient de ostream, mais je suis pas sur que ostream se
laisse hériter gentillement.


Et surtout, qu'est-ce que tu fais quand on t'a passé un ostream& en
paramètre.

Je pourrais aussi avoir une méthode inTinyFormat qui retournerait un
type spécifique ce qui permettrait d'écrire

cout<<obj.inTinyFormat();

Mais bon, j'imagine que c'est un idiome classique.


La solution la plus fréquente, je crois, c'est de créer des classes
wrapper de formattage, du genre TinyObject et LargeObject, qui prenent
l'objet comme paramètre et s'occupent de le formatter comme voulu.

Globalement, c'est la solution que je préfère en général. Mais il y a
des exceptions -- je verais bien des manipulateurs pour polar et
cartesian pour un complex, par exemple.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
James Kanze
Christophe de Vienne writes:

|> Marc Boyer wrote:
|> > Samuel Krempp wrote:
|> >> oui, ou dans l'autre sens, faire des sur-types qui servent juste
|> >> à indiquer le formattage, c'est courant, et appeler le
|> >> constructeur (ou un helper qui créé) :

|> >> cout << TinyFormat(obj);

|> >> c'est un poil plus joli.

|> > Question de gout surement, mais quand je vois constructeur,
|> > j'ai tendance à penser "nouvel objet", avec
|> > construction/destruction (et les questions de perfs associées)

|> Mais que représente l'instanciation d'un objet à priori
|> 'léger' (TinyFormat contiendra juste un pointeur vers l'objet
|> à afficher) sur la pile, comparé à l'envoi de données
|> vers un flux ?

|> C'est surement négligeable, surtout si les fonctions du helper
|> sont inlinée par le compilo.

C'est probablement moins cher que la solution avec ios::xalloc. En
revanche, il pourrait éventuellement poser des problèmes de la
durée de vie de l'objet -- pas dans son utilisation typique, mais
rien n'exige que l'utilisateur ne l'utilse que de cette façon.

Ceci dit, il m'arrive d'utiliser de telles classes « wrapper »,
qui ne contiennent qu'un pointeur vers un autre objet, en espérant
que l'autre objet à une durée de vie suffisante. Mais c'est une
restriction que je ne manque pas de citer dans la documentation.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
Marc Boyer
wrote:
Marc Boyer wrote in message
news:<bmoe8v$4gg$...
Imaginons que mon objet obj puisse avoir deux formats de sortie: tiny
et large.


Seulement deux ? Et à quoi sert std::ios_base::width().


En fait, les formats serait "aut", "dot", "bcg" et ça
peut encore augmenter, mais je voulais pas entrer dans
les détails (mais j'aurais peut-être du).

Difficile d'aller modifier std::cout pour qu'il accepte
cout<<tiny ou cout.setf(tiny).


Pour que ça marche avec setf, en effet. Mais il n'y a pas de problème
pour en créer un manipulateur. Jette un coup oeil à côté de
ios_base::xalloc, ios_base::iword et ios_base::pword.


Je connaissais pas, je vais aller voir.

J'avais pensé à définir des classes tinyObjOstream et largeObjOstream
qui hériteraient de ostream, mais je suis pas sur que ostream se
laisse hériter gentillement.


Et surtout, qu'est-ce que tu fais quand on t'a passé un ostream& en
paramètre.


Je pensais avoir un format par défaut.

cout<<obj.inTinyFormat();

Mais bon, j'imagine que c'est un idiome classique.


La solution la plus fréquente, je crois, c'est de créer des classes
wrapper de formattage, du genre TinyObject et LargeObject, qui prenent
l'objet comme paramètre et s'occupent de le formatter comme voulu.

Globalement, c'est la solution que je préfère en général. Mais il y a
des exceptions -- je verais bien des manipulateurs pour polar et
cartesian pour un complex, par exemple.


Bon, autant prendre un idiome standard alors.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(