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 :

passer une fonction en paramètre d'une autre fonction


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 50
    Points : 26
    Points
    26
    Par défaut passer une fonction en paramètre d'une autre fonction
    Bonjour,
    je voudrai savoir comment faire pour passer une fonction en paramètre d'une autre fonction.
    Voici les fonctions :

    CVodeMalloc(_statesize, CVode_f, _timenow, _cvode_y, BDF, NEWTON, SS, &_reltol, &_abstol, NULL, NULL, TRUE, _iopt, _ropt, _MachEnv)

    CVode_f(int N, double time, N_Vector y, N_Vector ydot, void *f_data)

    La fonction CVodeMalloc() fait partie d'un module, une sorte de "boîte noire" et je n'ai pas le droit d'y toucher, par contre j'ai le code de CVode_f mais je ne pense pas que ce soit utile de l'avoir ici.

    Voilà, j'espère que c'est clair, dans le cas contraire, n'hésitez pas à poser des questions !

  2. #2
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    je voudrai savoir comment faire pour passer une fonction en paramètre d'une autre fonction
    En mettant simplement son nom comme argument lors de l'appel à la fonction. La fonction passée en argument doit avoir le type correspondant à celui du paramètre.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 50
    Points : 26
    Points
    26
    Par défaut
    La fonction passée en argument doit avoir le type correspondant à celui du paramètre.
    Quand tu parles du type de la fonction, tu veux dire le type qu'elle renvoie ? De toute façon CVode_f ne renvoie rien, ce serait plus une procédure en fait : si la logique tien toujours, il faudrait que le type du paramètre soit void ?

  4. #4
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 861
    Points
    11 861
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int f(int a,int b) { return a+b; }
     
    typedef int (*FunctionType)(int,int);
     
    void printNumFunc(FunctionType myfunction)
    {
    std::cout << myfunction(1,2) << std::endl;
    }
    C'est bien ce dont il s'agit ?

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Points : 1 069
    Points
    1 069
    Par défaut
    C'est une question de C.

    En C++, tu ne devrais pas avoir à utiliser des pointeurs de fonctions.

    Les mécanismes de conception orientée objet sont suffisamment riches pour pouvoir se passer de la notion de pointeur de fonction.

  6. #6
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 861
    Points
    11 861
    Par défaut
    En C++ on peut écrire des foncteurs, utiliser boost::function, ...

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Points : 1 069
    Points
    1 069
    Par défaut
    Voici un exemple de foncteur qui pourra te permettre de résoudre ton problème en C++.

    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
     
    #include <iostream>
     
    struct FunctionType {
      int f(int a,int b) {
        return a+b;
      }
    };
     
    void printNumFunc(FunctionType f_data) { 
      std::cout << f_data.f(1,2) << std::endl; 
    }
     
    int main () {
      FunctionType f;
      printNumFunc (f);
      return 0;
    }
    Désolé Alp, j'ai repiqué ton exemple. Je n'ai pas eu le courage de reprendre les 15 paramètres de setsuko974.

    Tu n'écris guère plus de ligne, tu n'utilises pas de pointeur de fonctions, tu n'as donc pas à te rappeler la syntaxe des pointeurs de fonctions et c'est simple à se rappeler puisque ça se résume à la définition d'une classe.

  8. #8
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    aoyou, tu n'as pas trop du comprendre les foncteurs.
    Ton code ne résout rien.

    Il faut faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<typename F>
    void printNumFunc(F f_data)

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Points : 1 069
    Points
    1 069
    Par défaut
    Effectivement, je n'aurais pas dû parler de foncteur. C'était juste pour montrer comment on pouvait se passer d'un pointeur de fonction.
    Donc, voilà ce que ça donne avec un vrai foncteur.

    Il faudrait un peu compléter l'exemple pour dériver d'une première classe. Dans ce cas, tu ne peux appeler qu'une fonction particulière mais le principe est là.

    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
     
    #include <iostream>
     
    struct FunctionType{
      virtual int operator () (const int a, const int b) const {
        return a + b;  // là à la place tu peux appeler ta fonction CVodeMalloc en ajoutant plus de paramètres à l'opérateur
      }
    };
     
    void printNumFunc(FunctionType f_data) { 
      // l'opérateur () permet d'une certaine façon d'utiliser une classe comme une fonction
      std::cout << f_data(1,2) << std::endl;
      // d'où fonction devient foncteur
    }
     
    int main () {
      FunctionType f;
      printNumFunc (f);
      return 0;
    }
    En fait, on appelle foncteur toute classe surchargeant l'opérateur () et c'est la définition reconnue.
    Désolé, loufoque mais la définition que tu donnes n'est pas celle d'un foncteur. Par contre, les templates sont ensuite fortement utilisés pour généraliser la notion de foncteur (cf. la STL).

  10. #10
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Quand tu parles du type de la fonction, tu veux dire le type qu'elle renvoie ? De toute façon CVode_f ne renvoie rien, ce serait plus une procédure en fait : si la logique tien toujours, il faudrait que le type du paramètre soit void ?
    non, le type du paramètre inclus le type de retour et le type des arguments. Le type d'une fonction ne se résume pas au seul type de la valeur de retour

  11. #11
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    N'ayant pas le droit de toucher a la signature de la fonction qui prend le pointeur, je vois mal comment il pourrait remplacer ce dernier par un foncteur.

    Ne nous ayant pas montré la déclaration de CVodeMalloc, seulement un example d'appel, on ne peut pas te dire la signature attendue. Si l'on suppose que la signature de ta deuxieme fonction est bonne (correspond à celle attendue) : void (*f)(int, double, N_Vector, N_Vector, void*) Alors qu'elle est l'erreur lors de l'appel ?

    Comme écrit dans ton premier post, tu vois que le pointeur vers la fonction est simplement le nom de la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CVodeMalloc(_statesize, CVode_f, _timenow, _cvode_y, BDF, NEWTON, SS, &_reltol, &_abstol, NULL, NULL, TRUE, _iopt, _ropt, _MachEnv)
    Si la fonction était globale mais que tu l'a déplacée dans une classe en méthode membre, alors vas voir la faq C++, le sujet y est traité.

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Points : 1 069
    Points
    1 069
    Par défaut
    Oups, on oublie tout...
    J'ai cru qu'il voulait passer sa fonction à CVode_f.

    C'est donc une question de C...

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 50
    Points : 26
    Points
    26
    Par défaut
    Citation Envoyé par diogene
    non, le type du paramètre inclus le type de retour et le type des arguments. Le type d'une fonction ne se résume pas au seul type de la valeur de retour
    Ben, si ces 2 types sont différents, comment on fait pour connaitre le type de la fonction ??

    Citation Envoyé par Alp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int f(int a,int b) { return a+b; }
     
    typedef int (*FunctionType)(int,int);
     
    void printNumFunc(FunctionType myfunction)
    {
    std::cout << myfunction(1,2) << std::endl;
    }
    C'est bien ce dont il s'agit ?
    C'est exactement ça ! Tu peux m'expliquer ton typedef ??

    Citation Envoyé par aoyou
    Oups, on oublie tout...
    J'ai cru qu'il voulait passer sa fonction à CVode_f.

    C'est donc une question de C...
    Il faut passer CVode_f à CVodeMalloc. En fait le programme était en C à la base mais il a été "transformé" en C++.

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Le typedef indique "pointeur sur fonction prenant deux int et retournant un int".
    Si le mot-clé typedef n'était pas là, la ligne aurait déclaré une variable de type "pointeur de fonction pren..." etc.

    Bref, le type complet d'une fonction, c'est son type de retour+celui de ses paramètres.

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 50
    Points : 26
    Points
    26
    Par défaut
    Citation Envoyé par Médinoc
    Bref, le type complet d'une fonction, c'est son type de retour+celui de ses paramètres.
    Donc (je me répète, je sais), si le type de retour et le/les types du/des paramètres d'une fonction sont différents, ça veut dire que la fonction a plusieurs types ?

    Voici un exemple d'appel de CVodeMalloc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    cvode_mem = CVodeMalloc(statesize, CVode_f, timenow, cvode_y, BDF, NEWTON, 
    							SV, &reltol, ew, NULL, NULL, TRUE, iopt, ropt, MachEnv);
    CVodeMalloc retourne un pointeur pour allouer de la mémoire ou NULL si ça n'a pas marché, et le problème que j'ai c'est que pour l'instant ça retourne NULL et je pense que c'est parce que je lui passe mal CVode_f.

    Edit : autant pour moi... en fait le problème ne vient pas de là mais du 4ième paramètre de CVodemalloc qui est égal à NULL. En clair je me suis comblètement trompée quant à la nature du problème
    Merci quand même pour votre aide !!

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Pour commencer, quel est le prototype de CVodeMalloc() ?

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 20/08/2013, 14h38
  2. passer le nom d'une fonction comme paramètre d'une autre fonction?
    Par med_alpa dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 11/03/2010, 12h57
  3. Réponses: 16
    Dernier message: 26/05/2009, 13h32
  4. Réponses: 1
    Dernier message: 23/05/2006, 14h36
  5. [VB]Passage de Fonction en paramètre (d'une autre fonction)
    Par Australia dans le forum VB 6 et antérieur
    Réponses: 10
    Dernier message: 21/03/2006, 18h55

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