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 :

Pointeur de fonction à paramètres variables


Sujet :

Langage C++

  1. #1
    Membre éprouvé
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Juillet 2009
    Messages : 122
    Par défaut Pointeur de fonction à paramètres variables
    Bonjour à tous,

    peut-être est-ce la fatigue du vendredi soir mais je ne parviens pas à trouver une solution à un problème qui s'est posé à moi aujourd'hui...

    J'aimerais définir une classe de foncteur qui prenne un nombre N général de paramètres double et qui retourne un double. Bref, une fonction de R^N dans R à laquelle je pourrais ajouter les petites libertés que permet le design foncteur.

    Grosso modo, j'ai en tête quelque chose qui devrait ressembler à ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template<unsigned int N>
    class Fonction
    {
      public:
        typedef double (*FPtr)(double, ... , double); /* N arguments */
     
        Fonction(FPtr fonction) : m_fonction(fonction) {}
     
        /* Application de la fonction */
        double operator()(double x1, ... , double xN) { return m_fonction(x1, ... , xN); }
     
      private:
        FPtr m_fonction;
    };
    C'est le genre de chose qui fait nécessairement penser à des variadic templates... et je vois bien comment faire avec cela pour l'opérateur mais pas pour le typedef sur une fonction à N paramètres double retournant un double...

    Il y a peut-être une solution toute bête que je ne vois pas ([Mode Foutage de Gueule activé] ... je ne suis pas suceptible ). Si quelqu'un a une piste, je suis preneur!

    Merci et bon week-end à tous!

  2. #2
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Comme tu ne veux que des doubles, une solution plus simple (et peut être plus accessible si tu n'as pas de compilateur qui le fournis) que les variadic templates serait tout simplement de demander un conteneur de double comme paramettre.

    Par exemple un std::vector<double> ( ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const std::vector<double>& mes_valeurs
    pour être précis).

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Pourquoi ne pas utiliser std::function (ou boost::function si tu as un compilateur sans TR1 ni C++11) qui te permet déjà de construire des foncteurs ?

    Sinon, cela peut se faire avec Boost.Preprocessor :
    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    #include <boost\preprocessor.hpp>
     
    #define MAX_FONCTION_ARITY 10
     
    #define MA_FONCTION(z, N, text)\
       class FonctionImpl##N \
       {\
         public:\
           typedef double (*FPtr)(BOOST_PP_ENUM_PARAMS(N, double x));\
           FonctionImpl##N(FPtr fonction) : m_fonction(fonction) {}\
           double operator()(BOOST_PP_ENUM_PARAMS(N, double x)){ return m_fonction(BOOST_PP_ENUM_PARAMS(N, x));}\
         private:\
           FPtr m_fonction;\
       };
     
    BOOST_PP_REPEAT(MAX_FONCTION_ARITY,MA_FONCTION,"")
     
    template<unsigned int N> struct FonctionImplHelper;
     
    #define MA_FONCTION_IMPL_HELPER(z,N,text)\
       template<> struct FonctionImplHelper<N> { typedef FonctionImpl##N type; };
     
    BOOST_PP_REPEAT(MAX_FONCTION_ARITY,MA_FONCTION_IMPL_HELPER,"")
     
    #undef MA_FONCTION_IMPL_HELPER
    #undef MA_FONCTION
    #undef MAX_FONCTION_ARITY
     
     
    template<unsigned int N>
    class Fonction : public FonctionImplHelper<N>::type
    {
       typedef typename FonctionImplHelper<N>::type base;
       typedef typename base::FPtr FPtr;
    public:
       Fonction(FPtr f):base(f){}
    };
     
     
     
     
    #include <iostream>
    double f0()
    {
       std::cout<<"f0\n";
       return 0.;
    }
     
    double f1(double)
    {
       std::cout<<"f1\n";
       return 1.;
    }
     
    double f5(double,double,double,double,double)
    {
       std::cout<<"f5\n";
       return 5.;
    }
     
    int main()
    {
       Fonction<0> op0(f0);
       op0();
     
       Fonction<1> op1(f1);
       op1(1.);
     
       Fonction<5> op5(f5);
       op5(1.,2.,3.,4.,5.);
     
       return 0;
    }

  4. #4
    Membre éprouvé
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Juillet 2009
    Messages : 122
    Par défaut
    Merci pour vos réponses. Pour la proposition de Klaim, je ne peux pas utiliser les vector car il est important pour le projet de pouvoir utiliser des "vraies" fonctions (d'où le typedef).

    Je vais suivre la piste de 3DArchi et regarder du côté du preprocesseur de Boost... Je ne suis pas très familier de cet outil, on va voir

    Edit: ça marche vraiment bien, merci encore à 3DArchi pour son aide! Je passe en résolu.

  5. #5
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Citation Envoyé par Meseira Voir le message
    Merci pour vos réponses. Pour la proposition de Klaim, je ne peux pas utiliser les vector car il est important pour le projet de pouvoir utiliser des "vraies" fonctions (d'où le typedef).

    Je vais suivre la piste de 3DArchi et regarder du côté du preprocesseur de Boost... Je ne suis pas très familier de cet outil, on va voir

    Edit: ça marche vraiment bien, merci encore à 3DArchi pour son aide! Je passe en résolu.

    Je ne comprends pas du tout de quoi tu parles, il n'y a pas de rapport entre avoir un paramettre de fonction qui est un vector (ou un autre container) et une quelconque notion de "vrai fonction".

    Est-ce que tu veux dire que tu devais avoir impérativement un nombre variable de paramettre à l'appel de la fonction?

  6. #6
    Membre éprouvé
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Juillet 2009
    Messages : 122
    Par défaut
    Citation Envoyé par Klaim Voir le message
    Est-ce que tu veux dire que tu devais avoir impérativement un nombre variable de paramettre à l'appel de la fonction?
    Oui, je dois pouvoir gérer des fonctions de la forme double f(double x1, double x2) et double f(double x1, double x2, double x3), par exemple, et ce n'est pas moi qui en choisit la forme. Sinon, je suis d'accord avec toi, si cela n'avait tenu qu'à moi, une fonction de plusieurs variables est une fonction qui associe à un vecteur, un nombre réel... Donc un double f(std::vector v). En tout cas, merci pour t'être pencher sur mon problème.

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

Discussions similaires

  1. fonction à paramètres variables stockée dans une DLL.
    Par bertrand125 dans le forum Langage
    Réponses: 6
    Dernier message: 26/03/2014, 15h33
  2. Pointeurs de fonction membre à paramètres variables!
    Par nixmind dans le forum Langage
    Réponses: 11
    Dernier message: 29/09/2012, 03h12
  3. Réponses: 4
    Dernier message: 01/12/2005, 12h33
  4. Réponses: 9
    Dernier message: 24/05/2005, 16h34
  5. Réponses: 5
    Dernier message: 09/02/2005, 18h50

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