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 :

spécialisation comportement foncteur


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut spécialisation comportement foncteur
    Bonjour à tous,

    Je voudrais pouvoir spécialiser le comportement d'un de mes foncteurs suivant si le type passé au foncteur défini un typedef particulier (ici value_type):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    struct my_functor
    {
      template<typename T>
      void operator()(T const& t) { std::cout << "le type parametre ne definit pas value_type" << std::endl; }
     
      template<typename T>
      void operator()(T const& t) { std::cout << "le type parametre definit value_type" << std::endl; }
     
    };
    Et à l'utilisation ça donnerais ça:
    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
     
    struct T1
    {
      typedef int value_type;
    };
     
    struct T2
    {
    };
     
    int main()
    {
      my_functor f;
      T1 t1;
      T2 t2;
      f(t1);  //afficherai "le type parametre definit value_type"
      f(t2);  //afficherai "le type parametre ne definit pas value_type"
    };
    Je vois pas trop comment m'y prendre (j'ai toujours un peu de mal avec les spécialisations template... )

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,

    Plutôt que la spécialisation, il faut préférer la surcharge.
    Ensuite cela doit pouvoir se faire avec un SFINAE pour détecter la présence de value_type et std::enable_if pour choisir l'un ou l'autre.

    [edit]
    Ce qui pourrait donner quelque chose comme ça :
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    template<class T>
    struct has_value_type_impl
    {
    private:
       struct yes {char dummy;};
       struct no {char dummy[2];};
     
    template<class T2> static yes f(typename T2::value_type*);
    template<class T2> static no f(...);
    public:
       static const bool value = sizeof(f<T>(0))==sizeof(yes);
    };
     
    template<class T>
    struct has_value_type : has_value_type_impl<T>{};
     
    #ifdef _MSC_VER
    template<bool, typename> struct enable_if;
    template<typename T> struct enable_if<true,T>
    {
        typedef T type;
    };
    #else // by defaut, assume enable_if available
    #include <type_traits>
    using std::enable_if;
    #endif
     
    #include <iostream>
     
    struct my_functor
    {
      template<typename T>
      typename enable_if<!has_value_type<T>::value,void>::type operator()(T const & t)
      { std::cout << "le type parametre ne definit pas value_type" << std::endl; }
     
      template<typename T>
      typename enable_if<has_value_type<T>::value,void>::type operator()(T const & t)
      { std::cout << "le type parametre definit value_type" << std::endl; }
     
     
    };
     
    struct T1
    {
      typedef int value_type;
    };
     
    struct T2
    {
    };
     
    int main()
    {
      my_functor f;
      T1 t1;
      T2 t2;
      f(t1);  //afficherai "le type parametre definit value_type"
      f(t2);  //afficherai "le type parametre ne definit pas value_type"
     
      return 0;
    }

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    Nickel! J'avais commencé à chercher du côté de SFINAE et boost::enable_if mais mon code était un poil plus compliqué que ce que tu proposes (même si en fait j'aurais dû obtenir un code similaire). Par contre c'est assez "lourd" d'avoir à coder la partie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template<class T>
    struct has_value_type_impl
    {
    private:
       struct yes {char dummy;};
       struct no {char dummy[2];};
     
    template<class T2> static yes f(typename T2::value_type*);
    template<class T2> static no f(...);
    public:
       static const bool value = sizeof(f<T>(0))==sizeof(yes);
    };
    Y'a pas moyen de faire plus simple? Il me semble me rappeler que JoelF avait commencé une lib pour savoir si une classe définissait un certain nombre de propriétés (membres, fonctions, types), je vais essayer de retrouver ça.
    Encore merci!

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par CedricMocquillon Voir le message
    Y'a pas moyen de faire plus simple? Il me semble me rappeler que JoelF avait commencé une lib pour savoir si une classe définissait un certain nombre de propriétés (membres, fonctions, types), je vais essayer de retrouver ça.
    Encore merci!
    Comme toujours, boost est ton ami :
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    #include <boost\mpl\has_xxx.hpp>
     
    BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type);
     
     
    #ifdef _MSC_VER
    template<bool, typename> struct enable_if;
    template<typename T> struct enable_if<true,T>
    {
        typedef T type;
    };
    #else // by defaut, assume enable_if available
    #include <type_traits>
    using std::enable_if;
    #endif
     
    #include <iostream>
     
    struct my_functor
    {
      template<typename T>
      typename enable_if<!has_value_type<T>::value,void>::type operator()(T const & t)
      { std::cout << "le type parametre ne definit pas value_type" << std::endl; }
     
      template<typename T>
      typename enable_if<has_value_type<T>::value,void>::type operator()(T const & t)
      { std::cout << "le type parametre definit value_type" << std::endl; }
     
     
    };
     
    struct T1
    {
      typedef int value_type;
    };
     
    struct T2
    {
    };
     
    int main()
    {
      my_functor f;
      T1 t1;
      T2 t2;
      f(t1);  //affichera "le type parametre definit value_type"
      f(t2);  //affichera "le type parametre ne definit pas value_type"
     
      return 0;
    }

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

Discussions similaires

  1. open avec comport
    Par Goldocrack dans le forum C++Builder
    Réponses: 6
    Dernier message: 15/04/2009, 08h12
  2. spécialisation d'un foncteur
    Par bobyjoe dans le forum C++
    Réponses: 2
    Dernier message: 06/07/2007, 09h00
  3. [Free Pascal] Comportement de Exec
    Par néo333 dans le forum Free Pascal
    Réponses: 3
    Dernier message: 01/11/2003, 17h46
  4. Distribution spécialisée apache ?
    Par FRANCKYIV dans le forum Développement
    Réponses: 5
    Dernier message: 23/10/2003, 15h46
  5. Réponses: 2
    Dernier message: 22/09/2003, 11h23

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