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 :

std::Bind : une fonction de type void sans arguments


Sujet :

C++

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut std::Bind : une fonction de type void sans arguments
    Bonjour,
    Je travail sur un interface utilisateur très simple pour un petit jeu.
    Dans la classe de l'interface nommée "UI", il y a une méthode: AddButton (pour ajouter un bouton à l'interface) qui prend en arguments les informations nécessaire à la création de ce bouton.

    Bien sûr, il y a une classe Button qui une fonction "BindAction" (lorsque le bouton est actionné, la fonction associée au bouton est exécutée).
    Le problème: c'est qu'il faut bien la relier cette fonction a mon pointeur dans la classe Bouton.

    La classe bouton:
    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
     
    //.h
    class Button
    {
    public:
    void BindAction(std::function<void()> *function);
    void PlayAction();
     
    private:
    std::function<void()> m_function;
    }
     
    //.cpp
    void Button::BindAction(function<void()> *function)
    {
    m_function = bind(&function);
    }
     
    void Button::PlayAction()
    {
    m_function();
    }
    La fonction d'ajout de bouton dans l'interface (en réalité elle est plus complexe mais je la simplifie en donnant que la fonction à bind):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void UI::AddButton(function<void()> function)
    {
    ButtonArray.push_back(Button()) //Ajout d'un bouton
    ButtonArray.back().BindAction(&function);
    }
    Et pour finir la création de l'UI + Bouton dans la le jeu en essayant de binder un simple fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    UI MyUI;
    MyUI.AddButton(&Game::TestFunction);
    La compilation ne s'effectue pas et j'ai tout un tas d'erreur en rapport avec la "functional.h":

    error C2664: 'void std::_Func_class<_Ret,>::_Set(std::_Func_base<_Ret,> *)' : cannot convert argument 1 from '_Myimpl *' to 'std::_Func_base<_Ret,> *'
    1> with
    1> [
    1> _Ret=void
    1> ]

    Je ne vous donne qu'une partie mais d'après ce que j'ai compris ça un rapport avec l'emplacement de la fonction dite (Game:: ).
    Le problème c'est que je n'es pas trouvé de tuto ou d'exemple sur le std::bind de fonction de type void ne prenant pas d'arguments
    Cependant, il existe peut être une autre méthode plus simple pour mon problème étant donné le simple "reliage" de deux fonctions !

    Merci

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Button::BindAction(function<void()> *function)
    {
    m_function = bind(&function);
    }
    Je ne me rappelle pas que bind() serve à cela, et je ne comprends pas pourquoi l'étoile, d'ailleurs: Ceci ne suffit-il pas?
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Button::BindAction(function<void()> function)
    {
    m_function = function;
    }

    Ce à quoi bind() sert, dans mes souvenirs, c'est à créer une function<void()> à partir d'une function<void(quelqueChose)> et d'un quelqueChose.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut
    Hum... ah ok.
    Donc il n'est pas possible de faire une sorte de "raccourci" de la fonction ?
    J'avais déjà vu cette technique de "bindage" dans Unreal Engine par exemple.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Je ne comprends pas ce que tu cherches à faire? std::function est déjà un pointeur de fonction (ou équivalent)... Et là, tu voudrais un pointeur de pointeur de fonction?

    Ou plutôt, un "pointeur de fonction", qui, à chaque appel, déréférence un pointeur de pointeur de fonction pour appeler la fonction du pointeur pointé?

    Dans ce cas, je préconiserais un truc du genre:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void dereferenceEtAppelle(function<void()> *ppf)
    {
    	function<void()> pf = *ppf;
    	pf();
    }
     
    ...
     
    function<void()> pfPointe;
     
    ...
     
    function<void()> pfQuiDereference = bind(dereferenceEtAppelle, &pfPointe);
    Et là, tu pourras passer pfQuiDereference à ton objet...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UI MyUI;
    MyUI.AddButton(std::bind(&Game::TestFunction, &instance_de_game)); // ou une lambda
    Les fonctions membres ont un paramètre caché: le pointeur d'instance (this).

    Et je rejoins Médinoc, un pointeur de std::function est louche.

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut
    Oui en gros j'ai besoin juste d'un pointeur de fonction qui pointe sur une fonction (que j'aurai choisi).
    Et je peux simplement appeler cette fonction avec le pointeur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    AddButton(&Game::TestFunction);
     
    void AddButton(function<void()> &function)
    {
    Button.BindAction(function);
    }
     
    void BindAction(function<void()> &function)
    {
    m_function = &function;
    }
    sauf que j'ai toujours mon erreur

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    @herotom99: bind() sert aussi à faire une function<void()> à partir d'une function<void Game::()> et d'un Game*, tu sais...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut
    Citation Envoyé par jo_link_noir Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UI MyUI;
    MyUI.AddButton(std::bind(&Game::TestFunction, &instance_de_game)); // ou une lambda
    Les fonctions membres ont un paramètre caché: le pointeur d'instance (this).

    Et je rejoins Médinoc, un pointeur de std::function est louche.
    Ok c'est bon ça fonctionne Donc je n'es apparemment pas compris l'utilité de std::bind. Je vais aller plus me renseigner.

    Le pointeur de fonction m'est utile car la classe bouton doit pouvoir servir pour n'importe quelle fonction. Et le pointeur permet de pointer la fonction à exécuter lors de la pression du bouton APRES la création du bouton.

    Merci à vous !

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Citation Envoyé par herotom99 Voir le message
    Et le pointeur permet de pointer la fonction à exécuter lors de la pression du bouton APRES la création du bouton.
    Ce que tu peux déjà faire avec un std::function<void()> normal, en rappelant la méthode void Button::BindAction(function<void()> function) avec la nouvelle fonction...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

Discussions similaires

  1. Réponses: 30
    Dernier message: 27/03/2008, 15h02
  2. Réponses: 3
    Dernier message: 19/03/2008, 22h11
  3. Appeler une fonction du type CreateFcn
    Par cococococococo dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 22/06/2007, 04h22
  4. Appeler une fonction d'un script sans action particulière
    Par blanchonvincent dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 06/05/2007, 22h29
  5. Réponses: 5
    Dernier message: 13/03/2006, 15h21

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