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 :

Variadic templates et std::function


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre Expert
    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
    Par d�faut Variadic templates et std::function
    Bonjour,

    Je cherche � faire marcher un code du genre :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    template<typename... args>
    int func(std::function<int(args...)> f)
    {
       return sizeof...(args); // juste pour tester
    }
    Avec ensuite :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
    int f2(int a, int b, int c)
    {
        return a + b + c;
    }
    Le code suivant compile bien :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    std::function<int(int, int, int)> f3 = f2;
    func(f3); // renvoie bien 3
    En revanche, celui-ci ne compile pas :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    func(f2); /* error: no matching function for call to ‘func(int (&)(int, int, int))’
    test.cpp:45:25: note: candidate is:
    test.cpp:28:5: note: template<class ... args> int func(std::function<int(args ...)>)
    test.cpp:28:5: note:   template argument deduction/substitution failed:
    test.cpp:45:25: note:   mismatched types ‘std::function<int(args ...)>’ and ‘int (*)(int, int, int)’ */
    Et celui-ci non plus :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    func([](int a, int b, int c) { return f2(a,b,c); }); /* error: no matching function for call to ‘func(main()::<lambda(int, int, int)>)’
    test.cpp:44:68: note: candidate is:
    test.cpp:28:5: note: template<class ... args> int func(std::function<int(args ...)>)
    test.cpp:28:5: note:   template argument deduction/substitution failed:
    test.cpp:44:68: note:   ‘main()::<lambda(int, int, int)>’ is not derived from ‘std::function<int(args ...)>’ */
    Pour le premier cas, je peux fournir un overload :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    template<typename... args>
    int func(int (*f)(args...))
    {
        return sizeof...(args);
    }
    Pas tr�s �l�gant, mais �a marche. En revanche, pour le deuxi�me cas, je ne vois pas comment faire sans fournir l�ensemble des surcharges jusqu�� n arguments, ce qui est justement ce que je souhaitais �viter avec les templates variadic.

    Mon compilateur est gcc 4.7.2, je ne peux pas en changer. Des suggestions ?

  2. #2
    Membre �m�rite
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Par d�faut
    Bonjour,

    Dans ton exemple, tu renvoies les nombre de param�tres de la fonction avec pour commentaire "juste pour tester".
    Quel est le but r�el derri�re ce test ?
    Il y a plusieurs mani�res de g�rer ce genre de probl�mes mais pour �a il faudrait voir qu'est-ce que c'est r�ellement cens� faire au final.

  3. #3
    Membre Expert
    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
    Par d�faut
    Dans le code r�el, �a renvoie une lambda dont le r�le sera d�appeler f avec des param�tres lus depuis une structure, stock�s temporairement dans un vecteur, apr�s avoir v�rifi� un certain nombre de contraintes sur ces param�tres. En gros, l�id�e, c�est de d�coupler la partie � r�cup�ration et v�rification des param�tres � (qui viennent d�appels jsonrpc), assez syst�matique et r�p�titive, de la partie m�tier, et de la faire de mani�re g�n�rique (v�rification de pr�sence et type de chacun des arguments, appel de la fonction m�tier avec les arguments individuels si ok, sinon erreur).

    Oui, c�est un petit peu compliqu�, c�est pour �a que j�ai essay� de simplifier au maximum pour montrer le point qui me bloque actuellement.

  4. #4
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    F�vrier 2009
    Messages
    762
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2009
    Messages : 762
    Par d�faut
    Salut,

    Pourquoi pas quelque chose dans cette veine :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    template<class Fun>
    int func(Fun f)
    {
       return boost::function_traits<Fun>::arity; // pas sur de la syntaxe mais bon l'idée est là.
    }
    L'id�e est d'�tre simplement plus g�n�ral. D'habitude c'est de cette mani�re qu'on passe des fonctions en argument.

  5. #5
    Membre Expert
    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
    Par d�faut
    Effectivement, j�avais n�glig� cette possibilit� (du fait que j�ai certains param�tres fix�s, le type de la valeur de retour fix�, etc).

    N�anmoins, ce n�est pas bon quand m�me :
    test.cpp: In instantiation of �int func(Fun) [with Fun = main()::<lambda(int, int, int)>]�:
    test.cpp:57:68: required from here
    test.cpp:43:53: error: �value� is not a member of �boost::function_types::function_arity<main()::<lambda(int, int, int)> >�
    (pour les non lambdas, �a fonctionne bien).

  6. #6
    Membre Expert

    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Ao�t 2004
    Messages
    1 391
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 35
    Localisation : France, Doubs (Franche Comt�)

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

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 1 391
    Par d�faut
    Pour la question initiale, la r�ponse devient clair si tu te mets � la place du compilateur. On te donne un truc de type A et tu dois le faire matcher avec un type B<T>, tu fais comment ? Comment tu peut savoir � l'avance si un B<T0> va proposer un constructeur depuis un A ? Tu ne peux pas (tout tester n'est pas envisageable (*)). Quand tu lui passes un A=B<T0> la probl�matique dispara�t puisqu'on trouve un T qui fait parfaitement correspondre les types (**).

    Ta probl�matique de fond, c'est vraiment l'arit� ? Parce que je ne suis pas convaincu qu'il y ai une vraie solution � cette probl�matique. Si je passe un foncteur polymorphe avec un Arg... qui fait du forward, la fonction fait quoi ? Cependant, si la question c'est vraiment l'arit�, c'est une m�ta-fonction (***) qu'il faut chercher � faire, pas une fonction (c'est purement compile-time comme information).

    (*) Surtout qu'il faudrait ordonner les diff�rentes possibilit�s ensuite ...
    (**) Modulo le const, volatile, &, &&, mais le compilateur les ignore pour la proc�dure de correspondance.
    (***) Dans l'id�e il faut que tu envisages tout les cas possibles (que tu veux traiter) de foncteur, que tu fasses un my_meta_fn<> sp�cialis� pour chacun de ces cas avec un Arg... sur lequel faire un sizeof...(Arg).

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. R�ponses: 4
    Dernier message: 30/05/2011, 19h38
  2. R�ponses: 2
    Dernier message: 10/01/2009, 13h38
  3. Probl�me de class template et std::map
    Par bathof dans le forum Langage
    R�ponses: 2
    Dernier message: 31/07/2007, 22h18
  4. template et std::vector
    Par themadmax dans le forum Langage
    R�ponses: 9
    Dernier message: 26/07/2006, 10h41

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