IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Méthode variadic arguments


Sujet :

Langage C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2022
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Février 2022
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Méthode variadic arguments
    Bonjour,
    J'ai une méthode comportant un nombre d'arguments variable.
    Exemple : methode(char* x, char* y, int i, ...)
    Les 3 premiers arguments sont "fixes" mais pas les suivants.
    J'utilise va_list pour récupérer les paramètres variables.

    J'aimerais savoir comment faire pour connaitre/récupérer le nombre d'arguments passés à cette méthode lorsque l'on se trouve dedans grâce notamment à ce va_list ?

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    C'est du C c'est pour cela que l'entête en C++ est cstdarg au lieu de stdarg.h.

    <cstdarg> (stdarg.h), documentation cplusplus.com en anglais

    Et si tu lis la fonction va_arg, on peut lire 1 remarque :
    Notice also that va_arg does not determine either whether the retrieved argument is the last argument passed to the function (or even if it is an element past the end of that list). The function should be designed in such a way that the number of parameters can be inferred in some way by the values of either the named parameters or the additional arguments already read.
    En gros, il te dit que les ellipses ne savent pas le nombre d'arguments : il faut avoir soit 1 variable soit 1 paramètre.

    Édit : ce n'est pas évoqué mais 1 sentinelle (1 valeur connue en dernier argument) peut fonctionner.

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    A vrai dire, des char* et des va_list, c'est tellement peu utilisé en C++ que l'on a déjà un problème:

    Soit tu essaye de faire quelque chose en C -- en utilisant éventuellement des choses du C++ comme std::cin ou std::cout, ce qui ne serait vraiment pas une bonne chose -- et on peut considérer que tu t'es trompé de section, que la section dédiée au C serait largement plus adéquate.

    Soit il faut complètement changer de méthode de travail afin de pouvoir travailler effectivement en C++ sans essayer d'avoir recours à des pratiques issues du C et qui sont, le plus souvent, sources d'énormément de problèmes.

    Il faut en effet savoir que, même si C++ ne renie absolument pas sont héritage venu du C, C et C++ sont deux langages aussi différents que ce que pourraient être le Français et le latin de Jules Cesar, si bien que des pratique "habituelles et tout à fait correctes" en C sont souvent inefficaces et dangereuses en C++.

    Je crains donc que, en l'état, tu peine énormément à obtenir une réponse correcte et, surtout, adaptée à ton problème. Il serait donc largement préférable de commencer par apporter quelques précisions, parmi lesquelles:

    1- Veux tu coder en C ou en C++

    Si tu veux utiliser le C, tu devrais (abandonner l'utilisation de cin et de cout, mais cela, tu t'en doutes) demander à la modération de déplacer la discussion dans la section ad-hoc.

    Si tu veux coder, en C++, nous en dire un peu plus sur tes besoins et tes souhaits, c'est à dire:
    1. Qu'est censée faire la fonction en question (au moins dans les grandes lignes)
    2. à quoi sont censés servir les paramètres fixes (au moins dans les grandes lignes)
    3. En quoi crois tu avoir besoin de connaitre le nombre de paramètre dont "tu ignore tout" (le contenu effectif de ta va_list actuelle) Est-ce
      1. ou parce que tu veux savoir quand tu arrive à la fin de ces paramètres
      2. parce que tu dois manipuler plusieurs de ces paramètres ensemble

    En C++, nous nous tournerions sans doute très facilement vers la programmation générique (les template) et la possibilité d'avoir ce que l'on appelle des variadic template (des template variadic), avec "juste ce qu'il faut" de récursivité pour que le compilateur fasse le gros du boulot.

    Ce que je ferais plus ou moins naturellement, ce serait sans doute de séparer la gestion des paramètres fixes de la gestion des paramètres dont on ignore tout, pour autant que cela ait du sens de travailler de cette manière. Et comme je n'ai aucune indication contraire quant à tes besoins pour l'instant, je suis tout à fait libre de considérer que cela en a

    Cela me permettra d'éviter que la partie qui est sensée s'occuper des paramètres fixes ne soit récupérée "par erreur" par le compilateur qui se trouverait dans une situation dans laquelle trois paramètres "dont on ne sait rien" pourrait correspondre à la liste des paramètres fixes
    Mon code va donc se composer:
    • d'une fonction qui sera appelée par l'utilisateur (foo), qui prend trois paramètres fixes, et "un nombre inconnu de paramètres dont on ne sait rien"
    • d'une fonction qui s'occupe de gérer les paramètres fixes ( common dans le code)
    • d'une fonction (details) qui s'occupe de faire un appel récursif permettant gérer l'ensemble des paramètres "dont on ne sait rien"
    • d'une surcharge de la cette fonction (détails) qui permet de mettre fin à la récursivité en gérant un seul de ces paramètres "dont on ne sait rien" à la fois

    Voici à quoi il pourrait ressembler:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    #include <iostream>
    /* ceci est la fonction qui s'occupe de traiter
     * les paramètres fixes
     */
    void base(const char * a, const char * b, int i){
        std::cout<<"base called with\n"
                 <<"a = "<<a<<"\n"
                 <<"b = "<<b<<"\n"
                 <<"i = "<<i<<"\n";
    }
    /* juste une déclaration de la fonction destinée
     * à traiter les paramètres dont on ne sait rien
     * Elle part cependant du principe qu'il y aura forcément
     * au moins un paramètre dont on ignore tout
     */
    template <typename T,typename ... ARGS>
    void details(T first, ARGS ... args);
    /* la version "terminale" de cette fonction:
     * elle s'occupe de traiter un paramètre 
     * "dont on ignore tout" et s'arrête après cela
     */
    template <typename T>
    void details(T first){
        std::cout<<"detailsfinal call with T="<<first<<"\n";
    }
    /* la version récursive de la fonction:
     * elle fait appel à la version finale pour le premier
     * paramètre, puis provoque la récursivité pour
     * le nombre inconnu de paramètres dont on ne sait rien
     */
    template <typename T,typename ... ARGS>
    void details(T first, ARGS ... args){
        std::cout<<"recursive call\n";
        otherDetails(first);
        otherDetails(args ...);
    }
    /* ceci est la fonction que l'on appelle réellement
     * avec trois paramètres fixes et 
     * "un nombre inconnu de paramètres dont on ne sait rien
     */
    template <typename ... ARGS>
    void foo(const char * a, const char * b, int i, ARGS ... args){
        /* elle fait appel à la fonction qui s'occupe de traiter
         * les paramètres fixes
         */
        base(a, b, i);
        /* suivi d'un appel à la fonction destinée à 
         * traiter les paramètres dont on ne sait rien
         */
        details(args ...);
    }
    /* l'utilisation de tout cela ressemblerait à quelque chose
     * comme
     */
    int main(){
        foo("salut","le monde", 3, 3.1415926,"truc",15);
        return 0;
    }
    Note, car cela pourrait t'inquiéter d'une manière ou d'une autre, que l'ensemble de la récursivité sera évalué au moment de la compilation, ce qui implique qu'il n'y aura absolument pas de perte de performances lorsque le programme sera exécuté. Bien au contraire: le compilateur ayant une vue globale et générale de tout ce qui doit être fait, il n'est même pas exclu qu'il trouve un moyen auquel nous n'aurions jamais pensé d'optimiser tout cela

    Pour te convaincre que ce code pourrait parfaitement fonctionner: voici le résultat obtenu avec un compilateur en ligne. Si tu le souhaite, tu peux avoir accès au code assembleur qui a été généré (ainsi qu'au code binaire exécutable, d'ailleurs)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2022
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Février 2022
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Merci pour vos réponses.
    Je vais regarder de mon côté en prenant en compte vos conseils.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. méthode GET : argument contenant des arguments
    Par ypcman dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 23/02/2011, 08h08
  2. Méthode avec argument initialisé par défaut
    Par rtg57 dans le forum Langage
    Réponses: 3
    Dernier message: 15/02/2010, 16h23
  3. [POO] passer une méthode en argument
    Par gorgonite dans le forum Langage
    Réponses: 4
    Dernier message: 09/11/2007, 18h56
  4. [C#] Passage d'une méthode en argument
    Par Husqvarna dans le forum C#
    Réponses: 8
    Dernier message: 15/11/2006, 12h54
  5. Méthode avec argument objet de la même classe
    Par Black-Ghost dans le forum C++
    Réponses: 5
    Dernier message: 30/01/2006, 10h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo