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 :

Pointeur sur fonction templatisé


Sujet :

C++

  1. #1
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut Pointeur sur fonction templatisé
    Bonjour,

    J'ai une classe qui en fonction de diverses circonstances, doit appeler un foncteur par n foncteurs possibles.
    J'aimerais que ce foncteur soit défini comme membre, mais qu'il soit initialisé de manière dynamique.

    Dans le cas d'une fonction simple, je créerais un pointeur de fonction, et je ferais une affectation dynamique.

    Sauf que là, je suis en présence d'un foncteur dont le type de retour est templatisé.

    Est-il possible de faire quelque chose avec les nouvelles fonctionnalités de C++11 (std::function, decltype(), result_of...), ou dois-je passer par un tableau de pointeurs de fonctions ?

  2. #2
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Difficile à dire avec ta description.

    Néanmoins, il y a deux cas distincts :
    - le foncteur à appeler est vraiment connu à la compilation, statiquement : alors oui, ça doit être faisable avec des templates
    - le foncteur à appeler est connu à l’exécution uniquement : alors dans ce cas, le tableau de std::function s’impose.

    Mais si tu dois choisir parmi plusieurs foncteurs de types de retour différent, ça ne peut être fait *que* à la compilation (sinon, il te faudra un variant pour le type de retour -> mais un visiteur direct pourrait être plus approprié, du coup).

    Tu peux fournir un pseudo-code qui explique mieux ton besoin ?

  3. #3
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Ça confirme ce que je pensais, merci. Je voulais seulement savoir si C++11 offrait des magouilles pour s'en sortir.

    Sinon, j'ai un autre souci plus basique, lié à une histoire de syntaxe.

    Je n'arrive pas à affecter à un std::function une méthode membre non statique. Je triture toutes les syntaxes possibles, mais sans succès.

  4. #4
    Membre éprouvé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Points : 1 060
    Points
    1 060
    Par défaut
    Citation Envoyé par oodini Voir le message
    Ça confirme ce que je pensais, merci. Je voulais seulement savoir si C++11 offrait des magouilles pour s'en sortir.
    result_of et compagnie font de la résolution de type statique... Template et dynamisme à l'exécution = galère (type erasure, boost::any, boost::variant, etc.)

    Je n'arrive pas à affecter à un std::function une méthode membre non statique. Je triture toutes les syntaxes possibles, mais sans succès.
    C'est ça que tu cherches?

    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>
    #include <functional>
     
    class A {
    public:
     
    	double square(double x) const {
    		return x*x ;
    	}
     
    } ;
     
    //g++ --std=c++11 -o bind_member.exe main.cpp
    int main( int argc, char * argv[] ){
    	A a ;
    	std::function< double(double) > f = std::bind(&A::square,a,std::placeholders::_1) ;
    	std::cout << f(2) << std::endl;
    	return 0 ;
    }

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par bretus Voir le message
    C'est ça que tu cherches ?
    C'est bien possible. J'avais fini par comprendre qu'il fallait passer un pointeur sur l'instance, mais j'ai fait sans bind.
    L'affectation avait enfin réussi à compiler, et j'en avais tellement ma claque que je suis parti du taf. Je ne sais donc pas encore si ça fonctionne comme je le voudrais.

    Je ne doute pas que ta solution fonctionne. Je suis impatient de comparer avec ce que j'ai fait.

  6. #6
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Des tests que j’avais fait avec bind, c’était très sensiblement plus lent (d’un facteur 4) que d’utiliser une lambda.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::function< double(double) > f = [&a](int x) { return A.square(x);} ;

  7. #7
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Citation Envoyé par white_tentacle Voir le message
    Des tests que j’avais fait avec bind, c’était très sensiblement plus lent (d’un facteur 4) que d’utiliser une lambda.
    Intéressant oO . Une idée de comment se fait-ce ?
    -- Yankel Scialom

  8. #8
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Je pense que les lambdas dans gcc ont fait l’objet d’une plus grande phase d’optimisation que std::bind. Après, je ne sais pas si quelque chode lié à std::bind implique cette différence.

  9. #9
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Je suis en train de lire le dernier bouquin de Scott Meyers, et il y a justement un item titré "Préférez les lambdas à std::bind".
    Mais vu les conditions de lecture, et le fait que je ne sois pas très frais en ce moment (les vacances qui s'approchent ne seront pas superflues), je n'ai pas tout assimilé.
    Je referai une lecture demain.

  10. #10
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Tu mettais bien ton lambda dans un std::function avant de l'utiliser ? Sinon, il y a concurrence déloyale...
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  11. #11
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Tu mettais bien ton lambda dans un std::function avant de l'utiliser ? Sinon, il y a concurrence déloyale...
    Oui. Le test était bien std::bind vs lambda, chacun stocké dans un std::function (c’était mon cas d’utilisation et j’avais le choix entre les deux options, je voulais éviter de choisir celle qui présentait un surcoût dans la mesure où il n’y avait aucune plus value ni à l’une ni à l’autre).

    Par contre, j’ai refait des tests, comme tu m’as fait douter, et l’écart est moins important que ce que je signalais (plus proche d’un facteur 1,5 à 2 que de 4 à 5), avec les optimisations activées. J’ai changé de version de compilateur entre temps (gcc-4.7 -> gcc 4.9), donc ce n’est pas impossible non plus que ça joue, sinon c’est ma seulement ma mémoire qui a exagéré l’écart.

Discussions similaires

  1. Réponses: 10
    Dernier message: 03/02/2005, 13h09
  2. Réponses: 5
    Dernier message: 12/01/2005, 20h58
  3. pointeurs sur fonction en C++
    Par cemoi dans le forum C++
    Réponses: 7
    Dernier message: 29/11/2004, 13h19
  4. [langage] Pointeur sur fonction
    Par Fanch.g dans le forum Langage
    Réponses: 2
    Dernier message: 02/10/2004, 10h43
  5. Declaration de fonction retournant un pointeur sur fonction
    Par pseudokifaitladifférence dans le forum C
    Réponses: 5
    Dernier message: 11/08/2003, 19h37

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