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 ...
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>
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 ...
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 ...
Cyrille
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);
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);
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);
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.
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 :
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.
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.
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.
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 <<.
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 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.
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 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
Sylvain wrote:
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 :
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.
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 <<.
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 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.
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@neuf.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
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.
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 <<.
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 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.
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 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
Sylvain
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!
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.
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.
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.
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!
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.
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.
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.
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.
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.
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.