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 :

informations à la compilation pour une fonction membre


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Par défaut informations à la compilation pour une fonction membre
    Bonjour à tous,

    J'essaie de récupérer à la compilation le nombre d'arguments (et leur type) d'une fonction membre (en l'occurrence l'operateur()). Je ne vois pas comment m'y prendre, ni même si cela est possible (je suppose que oui). Je tripatouille un peu avec boost.function_types mais pas moyen de m'en sortir. En gros, j'aimerais avoir quelque chose comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template< class MyClass >
    struct bracket_operator_info
    {
       enum {arity = ... }
       typedef ... result_type;
       typedef ... arg1;
       .
       .
       .
    }
    Quelqu'un aurait-il une idée de la marche à suivre?

  2. #2
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    function_types::function_arity te renvoie une mpl integral constant définissant le nombre de paramètres.

    et function_types::parameter_types te renvoie une MPL sequence (random access)

  3. #3
    Membre expérimenté Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Par défaut
    Hello et merci de ta réponse.
    Je dois mal utiliser function_types. Pour l'instant, j'essaie ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct Test
    {
       int my_function(int val) {return val*2;}
    };
     
    int arity = boost::function_types::function_arity<&Test::my_function>::value;
    qui ne compile pas sous Visual 8 ('boost::function_types::function_arity'*: argument modèle non valide pour 'T', type attendu). Effectivement je passe un pointeur de fonction membre en paramètre, mais comment peut on faire autrement?

  4. #4
    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
    Tu peux passer par une fonction intermédiaire qui grace aux template déduit le type en fonction de paramètre, quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template<class T> size_t my_func(T)
    { return function_arity<T>::value; }
     
    //Utilisation
    my_func(&Test::my_function);
    Vérifie quand même que ca existe pas déjà dans boost.

    NB: J'ai pas boost sur la main pour tester que c'est bon, j'ai pris un function_arity de cette forme (avec variadic) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    template<class T>
    struct function_arity;
     
    template<class T, class R, class ...Arg>
    struct function_arity<R(T::*)(Arg...)>
    { enum { value = sizeof...(Arg) }; };
    (Celui de boost est évidament plus complet, c'était juste pour tester dans un cas particulier), Il faudra peut-etre adapter si c'est pas exactement ce genre de paramètre que boost attend (cf la doc).

  5. #5
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Hum, ouai utilise une function template. Mais tu parler de travailler avec des function object dans ce cas là ça marchera pas. (function arity ne marche qu'avec les builtin Callable). Pourquoi? Parce que c'est "pas faisable", parce qu'un functor peut avoir plusieurs arités...

    Mais y'a moyen de s'en sortir, proto propose quelque chose :
    http://www.boost.org/doc/libs/1_45_0...function_arity

  6. #6
    Membre expérimenté Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Par défaut
    Bon, j'avance un peu.

    @Flob90:

    La fonction intermédiaire est une bonne idée, je ne savais pas qu'il était possible d'utiliser un sizeof sur un appel de fonction. En fait c'est ce que boost function_traits fait quand la macro BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION est définie (type_traits/function_traits.hpp). Du coup une réécriture pour les pointeur de fonction membre fonctionne pour déterminer l'arité (copié collé depuis function_traits.hpp avec qqes changements):


    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
     
    template<unsigned N> 
    struct type_of_size
    {
      char elements[N];
    };
     
    template<typename Class, typename R>
    type_of_size<1> member_function_helper(R (Class::*f)());
     
    template<typename Class,typename R, typename T1>
    type_of_size<2> member_function_helper(R (Class::*f)(T1));
     
    //etc...
     
    template<typename Class>
    struct member_function_traits
    {
    	BOOST_STATIC_CONSTANT(unsigned, arity = (sizeof(member_function_helper(&Class::operator()))-1));
    };
    J'imagine qu'on peut généraliser le tout en renvoyant directement un boost::function_traits et en utilisant BOOST_TYPEOF:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    template<typename Class, typename R>
    boost::function_traits<R()> member_function_helper(R (Class::*f)());
     
    template<typename Class, typename R, typename T1>
    boost::function_traits<R(T1)> member_function_helper(R (Class::*f)(T1));
     
    //etc...
     
    template<typename Class>
    struct member_function_traits
    {
    	typedef BOOST_TYPEOF(member_function_helper(&Class::operator())) function_traits_type;
    };
    Ça fait ce que je souhaite mais reste un peu lourd et probablement pas du tout optimal.


    @Goten:
    J'ai l'impression que tout est possible avec proto mais cela reste au delà de mon niveau pour l'instant. Merci pour le lien, je vais prendre qqes jours pour essayer de digérer tout ca .

Discussions similaires

  1. [QtConcurrent] QtConcurrent::run() pour une fonction membre
    Par silvio78 dans le forum Multithreading
    Réponses: 4
    Dernier message: 29/03/2010, 17h29
  2. Demande d'information SQL pour une fonction VRAIFAUX
    Par Fredy17 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 14/03/2008, 02h07
  3. [Systeme d'Information] Quels conseils pour une refonte ?
    Par jejefeds dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 07/12/2005, 18h23
  4. paramètres pour une fonction
    Par bul dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 28/05/2005, 07h49
  5. Thread avec une fonction membre d'une classe
    Par SteelBox dans le forum Windows
    Réponses: 6
    Dernier message: 01/03/2004, 01h15

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