C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

passer une liste d'argument variable lors d'un appel
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
superbabar51@hotmail.com
Guest





PostPosted: Sat Apr 08, 2006 6:06 pm    Post subject: passer une liste d'argument variable lors d'un appel Reply with quote



Bonjour,

Comment est t-il possible de passer une liste d'argument variable à
une autre fonction?

Par exemple, considerons la fonction handle_error suivante:

void handle_error (int errorcode, std::string format, ...)
{
printf(format.c_str(), ...)
// où ... représente les arguments passés à handle_error
}

Est-ce possible (proprement)?

Merci
Back to top
Cyrille
Guest





PostPosted: Sat Apr 08, 2006 6:06 pm    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote



superbabar51 (AT) hotmail (DOT) com a écrit :
Quote:
Bonjour,

Comment est t-il possible de passer une liste d'argument variable à
une autre fonction?

Les listes d'arguments variables sont gérables en utilisant std::va_list
fourni par l'en-tête <cstdarg> et les macros va_start et va_end.
Pour les passer à une fonction, il faut que celle-ci accepte un
paramètre std::va_list. On ne peut pas simplement passer à la fonction à
arguments variables.

Pour std::printf, par exemple, il y a la fonction std::vprintf, dont le
prototype est:
int vprintf(const char *format, va_list ap);

Ta fonction handle_error s'écrirait donc ainsi:

using namespace std;

void handle_error ( int errorcode, string format, ... )
{
va_list args;
va_start( args, format.c_str() );
vprintf( format.c_str(), args );
va_end( args );
}

--
Sukuuru Ranburu For Ever
Back to top
Michel Decima
Guest





PostPosted: Sat Apr 08, 2006 6:06 pm    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote



superbabar51 (AT) hotmail (DOT) com a écrit :
Quote:
Bonjour,

Comment est t-il possible de passer une liste d'argument variable à
une autre fonction?

Par exemple, considerons la fonction handle_error suivante:

void handle_error (int errorcode, std::string format, ...)
{
printf(format.c_str(), ...)
// où ... représente les arguments passés à handle_error
}

Est-ce possible (proprement)?

voir les fonctions vprintf, vsprintf et vsnprintf, et <stdarg.h>

De memoire:

void handle_error (int errorcode, std::string format, ...)
{
va_list ap;
va_start(ap, format);
vprintf(format.c_str(), ap);
va_end(ap);
}

Il faut donner a va_start le nom du dernier argument avant la liste
des arguments variables (donc ici format). Je ne sais pas si ca marche
avec un std::string, j'utilise toujours un char const* dans ce genre
de fonctions, et je sais qu'il y a des restrictions sur les types
qu'on peut passer dans les ...
Back to top
Cyrille
Guest





PostPosted: Sat Apr 08, 2006 6:06 pm    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote

Michel Decima a écrit :
Quote:
Cyrille a écrit :

void handle_error ( int errorcode, string format, ... )
{
va_list args;
va_start( args, format.c_str() );
vprintf( format.c_str(), args );
va_end( args );
}


pourquoi utiliser c_str() dans l'appel a va_start ?

Pour rien, c'est une erreur.

--
Sukuuru Ranburu For Ever
Back to top
Michel Decima
Guest





PostPosted: Sat Apr 08, 2006 6:06 pm    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote

Cyrille a écrit :

Quote:
void handle_error ( int errorcode, string format, ... )
{
va_list args;
va_start( args, format.c_str() );
vprintf( format.c_str(), args );
va_end( args );
}


pourquoi utiliser c_str() dans l'appel a va_start ?
Back to top
Loïc Joly
Guest





PostPosted: Sat Apr 08, 2006 7:06 pm    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote

superbabar51 (AT) hotmail (DOT) com a écrit :
Quote:
Bonjour,

Comment est t-il possible de passer une liste d'argument variable à
une autre fonction?

Par exemple, considerons la fonction handle_error suivante:

void handle_error (int errorcode, std::string format, ...)
{
printf(format.c_str(), ...)
// où ... représente les arguments passés à handle_error
}

Est-ce possible (proprement)?

Souvent, en C++, on préfère chaîner les appels. Un truc du style :

handleError(errorCode, format).arg("Toto").arg(12).arg("Toto3")

Ou, avec la surcharge d'opérateurs :

handleError(errorCode, format) << "Toto" << 12 << "Toto3";

--
Loïc
Back to top
John Deuf
Guest





PostPosted: Sun Apr 09, 2006 11:06 am    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote

Loïc Joly :

Quote:
Est-ce possible (proprement)?

Souvent, en C++, on préfère chaîner les appels. Un truc du style :
handleError(errorCode, format).arg("Toto").arg(12).arg("Toto3")

Tout a fait. Exemple ici :
http://c.developpez.com/faq/cpp/?page=fonctions#CLASS_chainage_appels

--
John Deuf
Back to top
Sylvain
Guest





PostPosted: Sun Apr 09, 2006 3:06 pm    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote

Loïc Joly wrote on 08/04/2006 20:55:
Quote:

Souvent, en C++, on préfère chaîner les appels. Un truc du style :

handleError(errorCode, format).arg("Toto").arg(12).arg("Toto3")

Ou, avec la surcharge d'opérateurs :

handleError(errorCode, format) << "Toto" << 12 << "Toto3";


je crains que "en C++" signifie ici "pour un exercice de style".

si l'error handler en question ne fait qu'écrire l'information reçue
dans un fichier (stream, console, ...), cela peut fonctionner.

mais, même dans ce cas, si le gestionnaire d'erreur va jusqu'à arrêter
l'application (selon la sévérité de l'erreur) seul le premier argument
sera enregistré.

si, pour un autre mode, la méthode affiche un dialogue d'alerte, cela va
être un peu moins efficace (une alerte par argument!) (à moins de
recompliquer arbitrairement le gestionnaire avec des inputters muets et
un flusher bavard).

je pense qu'il est préférable de garder des objets spécialisés: utiliser
un (char) stream avec sa famille d'opérateurs d'injection d'un coté,
concevoir un gestionnaire d'erreur de l'autre; vouloir mettre l'usage de
l'un dans l'autre est source de duplication de code et ne parait pas
vraiment utile ni efficace.

Sylvain.
Back to top
superbabar51@hotmail.com
Guest





PostPosted: Sun Apr 09, 2006 6:06 pm    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote

Merci à tous!
Back to top
James Kanze
Guest





PostPosted: Sun Apr 09, 2006 7:06 pm    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote

Sylvain wrote:
Quote:
Loïc Joly wrote on 08/04/2006 20:55:

Souvent, en C++, on préfère chaîner les appels. Un truc du style :

handleError(errorCode, format).arg("Toto").arg(12).arg("Toto3")

Ou, avec la surcharge d'opérateurs :

handleError(errorCode, format) << "Toto" << 12 << "Toto3";

je crains que "en C++" signifie ici "pour un exercice de style".

C'est plus que pour un exércise de style. En C++, on ne peut pas
passer des types non POD à des varargs. Ce qui les rend à peu
près inutilisables.

Quote:
si l'error handler en question ne fait qu'écrire l'information
reçue dans un fichier (stream, console, ...), cela peut
fonctionner.

mais, même dans ce cas, si le gestionnaire d'erreur va jusqu'à
arrêter l'application (selon la sévérité de l'erreur) seul le
premier argument sera enregistré.

Pas chez moi. Au moins, pas avec la forme avec des <<.

Quote:
si, pour un autre mode, la méthode affiche un dialogue
d'alerte, cela va être un peu moins efficace (une alerte par
argument!) (à moins de recompliquer arbitrairement le
gestionnaire avec des inputters muets et un flusher bavard).

Encore une fois -- pas chez moi. Évidemment, dans mes
applications, il n'y a pas de dialogue d'alerte, parce que
normalement, il n'y a pas de terminal affecté au programme, mais
j'envoie bien des emails et d'autres choses semblables.

Quote:
je pense qu'il est préférable de garder des objets
spécialisés: utiliser un (char) stream avec sa famille
d'opérateurs d'injection d'un coté, concevoir un gestionnaire
d'erreur de l'autre;

C'est effectivement une solution simple et efficace. Si on
s'arrête à la gestion des erreurs, je ne vois pas besoin de plus
non plus.

Dans mon cas, j'avais à gérer un système plus complète de
logging, où il fallait bien rendre l'utilisation la plus simple
possible, pour qu'il soit réelement utilisé partout.

Quote:
vouloir mettre l'usage de l'un dans l'autre est source de
duplication de code et ne parait pas vraiment utile ni
efficace.

Je ne sais pas en ce qui concerne l'efficacité -- il a été assez
efficace pour les applications où je m'en suis servi. En
revanche, je ne vois pas ton point en ce qui concerne la
duplication du code -- les templates sont là pour ça.

--
James Kanze kanze.james (AT) neuf (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Back to top
Sylvain
Guest





PostPosted: Mon Apr 10, 2006 9:06 pm    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote

James Kanze wrote on 09/04/2006 20:35:
Quote:
si l'error handler en question ne fait qu'écrire l'information
reçue dans un fichier (stream, console, ...), cela peut
fonctionner.

mais, même dans ce cas, si le gestionnaire d'erreur va jusqu'à
arrêter l'application (selon la sévérité de l'erreur) seul le
premier argument sera enregistré.

Pas chez moi. Au moins, pas avec la forme avec des <<.

mais pas chez moi non plus mon brave monsieur!

non pas que je réserve l'instruction:
errorHdlr << "monTrucVachementPropreQuiSertAFlusher";
pour réaliser le traitement (vs la mise en tampon), mais juste que c'est
trop grotesque pour que je l'imagine.

Quote:
si, pour un autre mode, la méthode affiche un dialogue
d'alerte, cela va être un peu moins efficace (une alerte par
argument!) (à moins de recompliquer arbitrairement le
gestionnaire avec des inputters muets et un flusher bavard).

Encore une fois -- pas chez moi. Évidemment, dans mes
applications, il n'y a pas de dialogue d'alerte, parce que
normalement, il n'y a pas de terminal affecté au programme, mais
j'envoie bien des emails et d'autres choses semblables.

je n'en doute pas un instant! j'ai bien vu des codes se connectant sur
une base, locker N tables, écrire *un* octet, delocker le bouzin, perdre
la connection, ..., pour chaque octet injecté; donc je ne m'étonnerai de
rien.

Quote:
en ce qui concerne la
duplication du code -- les templates sont là pour ça.

excellente celle-là !! merci ! je la note en tête des histoires droles.

Sylvain.
Back to top
kanze
Guest





PostPosted: Tue Apr 11, 2006 10:06 am    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote

Sylvain wrote:
Quote:
James Kanze wrote on 09/04/2006 20:35:
si l'error handler en question ne fait qu'écrire
l'information reçue dans un fichier (stream, console,
...), cela peut fonctionner.

mais, même dans ce cas, si le gestionnaire d'erreur va
jusqu'à arrêter l'application (selon la sévérité de
l'erreur) seul le premier argument sera enregistré.

Pas chez moi. Au moins, pas avec la forme avec des <<.

mais pas chez moi non plus mon brave monsieur!

Alors, qu'est-ce que tu essayais à dire quand tu disais que seul
le premier argument sera enregistré.

Quote:
non pas que je réserve l'instruction:
errorHdlr << "monTrucVachementPropreQuiSertAFlusher";
pour réaliser le traitement (vs la mise en tampon), mais juste
que c'est trop grotesque pour que je l'imagine.

Mais je n'ai pas de truc (explicit, en tout cas) pour déclencher
le flush. J'exploite la durée de vie des temporaires, pour que
le tout soit transparent à l'utilisateur.

Quote:
si, pour un autre mode, la méthode affiche un dialogue
d'alerte, cela va être un peu moins efficace (une alerte
par argument!) (à moins de recompliquer arbitrairement le
gestionnaire avec des inputters muets et un flusher
bavard).

Encore une fois -- pas chez moi. Évidemment, dans mes
applications, il n'y a pas de dialogue d'alerte, parce que
normalement, il n'y a pas de terminal affecté au programme,
mais j'envoie bien des emails et d'autres choses semblables.

je n'en doute pas un instant! j'ai bien vu des codes se
connectant sur une base, locker N tables, écrire *un* octet,
delocker le bouzin, perdre la connection, ..., pour chaque
octet injecté; donc je ne m'étonnerai de rien.

Si tu écris des choses comme ça, c'est ton problème. Ça laisse
trainer des doutes sur ta compréhension de la gestion des
threads, mais tu ne serais pas le premier à faire ce genre de
bêtise.

Quote:
en ce qui concerne la duplication du code -- les templates
sont là pour ça.

excellente celle-là !! merci ! je la note en tête des
histoires droles.

Je ne comprends pas. Je n'ai pas de duplication du code, parce
que je me suis servi des templates. C'est une technique connue
et approuvée par ceux qui connaissent le C++.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
Sylvain
Guest





PostPosted: Tue Apr 11, 2006 8:06 pm    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote

kanze wrote on 11/04/2006 11:44:
Quote:

mais, même dans ce cas, si le gestionnaire d'erreur va
jusqu'à arrêter l'application (selon la sévérité de
l'erreur) seul le premier argument sera enregistré.

Pas chez moi. Au moins, pas avec la forme avec des <<.

mais pas chez moi non plus mon brave monsieur!

Alors, qu'est-ce que tu essayais à dire quand tu disais que seul
le premier argument sera enregistré.

je n'ai pas "essayé de dire" ... mais as-tu essayé de comprendre?

Quote:
non pas que je réserve l'instruction:
errorHdlr << "monTrucVachementPropreQuiSertAFlusher";
pour réaliser le traitement (vs la mise en tampon), mais juste
que c'est trop grotesque pour que je l'imagine.

Mais je n'ai pas de truc (explicit, en tout cas) pour déclencher
le flush. J'exploite la durée de vie des temporaires, pour que
le tout soit transparent à l'utilisateur.

ah les temporaires, un bon flush masqué dans un destructeur, j'ai bon
Monsieur devinette ?

mais alors, ton post précédent était:

Quote:
Pas chez moi. Au moins, pas avec la forme avec des <<.

peux-tu nous expliquer pourquoi ton destructeur serait géné par une
méthode (T& arg(X x)) et ne le serait pas par un opérateur << ??

dans le même temps, peux-tu nous expliquer comment loguer *une* fois la
même erreur survenue dans X (64, 128, ...) threads lancés simultanément
mais échouant tous pour la même raison (extérieure aux threads).

peux-tu également indiquer où placer ton temporaire dans une chaine
d'appels de méthodes (le C++ est procédurale, non?) d'où on sort par des
catch / throw en cascade ?

Quote:
je n'en doute pas un instant! j'ai bien vu des codes se
connectant sur une base, locker N tables, écrire *un* octet,
delocker le bouzin, perdre la connection, ..., pour chaque
octet injecté; donc je ne m'étonnerai de rien.

Si tu écris des choses comme ça, c'est ton problème. Ça laisse
trainer des doutes sur ta compréhension de la gestion des
threads, mais tu ne serais pas le premier à faire ce genre de
bêtise.

où as-tu lu que *j* 'écrivais des choses comme ça ?
quel rapport cela a-t-il avec des threads ?

Quote:
en ce qui concerne la duplication du code -- les templates
sont là pour ça.

excellente celle-là !! merci ! je la note en tête des
histoires droles.

Je ne comprends pas.

ben désolé alors.

Quote:
Je n'ai pas de duplication du code, parce que je me
suis servi des templates. C'est une technique connue
et approuvée par ceux qui connaissent le C++.

non, ceux qui connaissent le C++ savent que "déclarer" et "instancier"
une classe template "duplique" le code template en code concrêt; le
binaire ne contient (évidemment) pas la classe de définition mais autant
de code (dupliqué au type classe paramètre) que de classes générées.

cela t'aurait échapper ?

Sylvain.
Back to top
Arnaud Meurgues
Guest





PostPosted: Tue Apr 11, 2006 10:06 pm    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote

Sylvain wrote:

Quote:
Je n'ai pas de duplication du code, parce que je me
suis servi des templates. C'est une technique connue
et approuvée par ceux qui connaissent le C++.


non, ceux qui connaissent le C++ savent que "déclarer" et "instancier"
une classe template "duplique" le code template en code concrêt; le
binaire ne contient (évidemment) pas la classe de définition mais autant
de code (dupliqué au type classe paramètre) que de classes générées.

cela t'aurait échapper ?

Dites, ça vous dirait pas de vous calmer un peu. Parce que dire
n'importe quoi en agressant les autres et en prenant tout le monde pour
des imbéciles, ce n'est pas bien passionnant. Chercher absolument la
manière d'interprèter ce que dit l'autre de manière à que ce puisse être
faux au lieu de chercher à comprendre ce qu'il dit, c'est aussi très
pénible.

En l'occurrence, l'intérêt d'éviter la duplication de code, c'est
essentiellement pour la maintenance. Un code dupliqué (au niveau des
sources) pose des problèmes de maintenance si une erreur est corrigé
dans une des parties dupliquées et pas dans une autre.

Les templates permettent d'éviter la duplication de code... source.
J'imagine que c'est ce dont parlait James.

En revanche, je ne saisis pas le problème d'avoir du code binaire
dupliqué ? C'est par soucis de la taille de l'exécutable ?
--
Arnaud
Back to top
Sylvain
Guest





PostPosted: Tue Apr 11, 2006 11:06 pm    Post subject: Re: passer une liste d'argument variable lors d'un appel Reply with quote

Arnaud Meurgues wrote on 11/04/2006 23:53:
Quote:

Dites, ça vous dirait pas de vous calmer un peu. Parce que dire
n'importe quoi en agressant les autres et en prenant tout le monde pour
des imbéciles, ce n'est pas bien passionnant. Chercher absolument la
manière d'interprèter ce que dit l'autre de manière à que ce puisse être
faux au lieu de chercher à comprendre ce qu'il dit, c'est aussi très
pénible.

je suis très calme, je n'ai même aucune difficulté à rester calme face à
l'insignifiance.

que "les autres" (pourquoi ce pluriel?) arrêtent précisemment
*d'initier* les trolls imbéciles et je n'aurais pas le loisir de noter
leurs contradictions.

Quote:
En l'occurrence, l'intérêt d'éviter la duplication de code, c'est
essentiellement pour la maintenance. Un code dupliqué (au niveau des
sources) pose des problèmes de maintenance si une erreur est corrigé
dans une des parties dupliquées et pas dans une autre.

ah bon !
btw, là vous me prenez pas pour un imbécile, c'est ça ?

Quote:
Les templates permettent d'éviter la duplication de code... source.
J'imagine que c'est ce dont parlait James.

le thread parlait de "nombre variables d'argument", il me m'intéresse
pas de savoir ce dont James parle à propos de ces templates hors sujet
mais qui "chez lui" ...

Quote:
En revanche, je ne saisis pas le problème d'avoir du code binaire
dupliqué ? C'est par soucis de la taille de l'exécutable ?

j'ai dit "problème", "souci" ?? une fois de plus vous voulez par une
pirouette ("quel seraient les pbs inhérents à la taille d'un code")
masquer le fait que vos (pardon pour l'amalgame mais il ne me semble pas
déplacé) arguments étaient sans substances (n'apporte rien à la
question) et inexacts (ben oui, un template ça duplique).

Sylvain.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.