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

C++ Discussion :

Méthode variadic en parametre d'une méthode template


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut Méthode variadic en parametre d'une méthode template
    Bonjour à tous,
    Je suis en train de faire un test simple de capture d'une fonction par une autre.
    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
    template<typename ResultType, typename ParameterType1>
    void CaptureMethod(ResultType(*func)(ParameterType1)) {
    }
     
    template<typename ResultType, typename ParameterType1, typename ParameterType2>
    void CaptureMethod(ResultType(*func)(ParameterType1, ParameterType2)) {
    }
     
    template<typename ResultType, typename ParameterType1, typename ParameterType2, typename ParameterType3>
    void CaptureMethod(ResultType(*func)(ParameterType1, ParameterType2, ParameterType3)) {
    }
     
    int f1(int) { return 0;  }
    int f2(int, int) { return 0; }
    int f3(int, int, int) { return 0; }
     
    int main()
    {
    	CaptureMethod(f1);
    	CaptureMethod(f2);
    	CaptureMethod(f3);
    	return 0;
    }
    Ça c'est la version à l'ancienne, le truc c'est qu'il faut que je créer autant de surcharge que le nombre max de paramètre de la méthode que je veux capturer. Donc je me suis dit autant passer par les template variadic:
    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
    template<typename ResultType, typename... ParametersTypes>
    void CaptureMethod(ResultType(*func)(ParametersTypes...)) {
    }
     
     
    int f1(int) { return 0;  }
    int f2(int, int) { return 0; }
    int f3(int, int, int) { return 0; }
    int f10(int, int, int, int, int, int, int, int, int, int) { return 0; }
     
    int main()
    {
    	CaptureMethod(f1);
    	CaptureMethod(f2);
    	CaptureMethod(f3);
    	CaptureMethod(f10);
    	return 0;
    }
    Maintenant j'aimerais pouvoir capturer des fonctions qui ont un nombre de paramètres variables:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template<typename ResultType, typename... ParametersTypes>
    void CaptureMethod(ResultType(*func)(ParametersTypes...)) {
    }
     
     
    int fVariable(...) { return 0;  }
     
    int main()
    {
    	CaptureMethod(fVariable);
    	return 0;
    }
    Mais là ça ne compile pas (je suis sous Visual 2017). Est-ce possible de capturer une fonction à nombre de paramètres variables? J'avoue que là je n'ai pas trop d'idées.

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    5 176
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 5 176
    Points : 17 068
    Points
    17 068
    Par défaut
    Oui, mais il te faut une surcharge de la template (en plus de ce que tu as déjà)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    template<typename ResultType, typename ... ParametersTypes>
    void CaptureMethod(ResultType(*func)(ParametersTypes..., ...)) {
    }
    Là tu pourras capturer toutes les fonctions ayant des paramêtres suivis d'une ellipse.

    Explication: ... c'est une liste de paramêtres non typées, ce n'est pas un type. Donc, ne rentre pas ParametersTypes....
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    Merci beaucoup! Vraiment très fort!

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    octobre 2004
    Messages
    11 605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 605
    Points : 30 564
    Points
    30 564
    Par défaut
    Salut,

    Et puis: c'est quoi cette horrible utilisation de pointeurs de fonction Le simple fait que tu utilises des variadic template indique que tu compiles, au minimum, en suivant la norme C++11.

    Or, la classe std::function est apparue en même temps que cette norme.

    Pourquoi ne pas l'utiliser? elle utilise déjà les template variadic et tout et tout
    allez, un exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    template < typename RT, typename ... Args, typename Fun=std::function<RT(Args ...)> >
    RT CaptureMethod(Fun fun, Args ... args ){
       return fun(args ...);
    }
    int f1(int i) { return i;  }
    int f2(int i, int j) { return i+j; }
    int f3(int i, int j, int k) { return i+j+k; }
    int main(){
     
    	std::cout<<"f1 :"<< CaptureMethod<int>(f1, 1)<<"\n"
    	         <<"f2 :"<<CaptureMethod<int>(f2,1,2)<<"\n"
    	         <<"f3 :"<<CaptureMethod<int>(f3,1,2,3)<<"\n";
    }
    (le int donné en paramètre template est là pour fournir la seule chose que le compilateur ne saura pas (facilement) déduire : le type de retour de la fonction )
    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

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    octobre 2004
    Messages
    11 605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 605
    Points : 30 564
    Points
    30 564
    Par défaut Pour éviter de devoir donner le type de retour en paramètre template
    Notes d'ailleurs qu'il y a moyen d'éviter le type de retour comme paramètre template, à condition de prendre certaines décisions, et de s'y tenir.

    Par exemple, nous pourrions décider que le type de retour de la fonction sera toujours le type du premier paramètre reçu, et partir sur quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template <typename RT, typename ... Args>
    struct ReturnTypeExtractor{
        using returnType = RT;
        using functionType = std::function<returnType(returnType, Args ...)>;
    };
    Nous n'aurions alors plus qu'à modifier la liste template de CaptureMethod pour lui donner une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    template < typename ... Args, 
               typename Fun=typename ReturnTypeExtractor<Args ...>::functionType, 
               typename RT= typename ReturnTypeExtractor<Args ...>::returnType > 
    RT CaptureMethod(Fun fun, Args ... args ){
       return fun(args ...);
    }
    ce qui nous permettrait de l'appeler sous les formes proches de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int f1(int i) { return i;  }
    int f2(int i, int j) { return i+j; }
    int f3(int i, int j, int k) { return i+j+k; }
    int main(){
     
        std::cout<<"f1 :"<< CaptureMethod(f1, 1)<<"\n"
                 <<"f2 :"<<CaptureMethod(f2,1,2)<<"\n"
                 <<"f3 :"<<CaptureMethod(f3,1,2,3)<<"\n";
        return 0;
    }
    Avoues que c'est chouette, les templates, non
    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

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 19/10/2009, 11h00
  2. changer automatiquement les parametres d'une méthode
    Par wariom dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 19/05/2009, 09h45
  3. Réponses: 5
    Dernier message: 14/12/2007, 15h51
  4. Appel d'une méthode à partir d'un nom de méthode
    Par tnarol dans le forum Langage
    Réponses: 20
    Dernier message: 07/03/2007, 17h46
  5. [Reflection]Instanciation d'object en parametre d'une méthode
    Par mezoo dans le forum API standards et tierces
    Réponses: 19
    Dernier message: 31/08/2006, 12h00

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