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 :

classe de traits et conteneurs


Sujet :

C++

  1. #1
    Membre expert
    Inscrit en
    Janvier 2005
    Messages
    2 291
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 291
    Points : 3 212
    Points
    3 212
    Par défaut classe de traits et conteneurs
    Bonjour,

    J'ai une petite interrogation à propos des classes de traits lorsque l'on développe des conteneurs génériques (tels que STL ou boost). Prenons l'exemple suivant:

    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
     
    template<class T>
    struct A
    {
         T value;
          typedef T type;
    };
     
    template<class Conteneur>
    struc Traits
    {
       typedef Conteneur::type type;
    };
     
    template<class Conteneur>
    void maFonction(Conteneur c)
    {
        //def 1
       Conteneur::type a;
        //def2
        Traits<Conteneur>::type b;
    }
    D'après ce que j'ai compris c'est la seconde définition qui doit être utilisée, pourtant les tests que j'ai réalisés fonctionnent tout aussi bien avec la première. Pourquoi dois-je alors faire intervenir une classe de traits?

    Merci d'avance!!

  2. #2
    Membre du Club
    Inscrit en
    Janvier 2005
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 36
    Points : 43
    Points
    43
    Par défaut
    typiquement le trait devrai etre un parametre template de ta fonction, il permet de fournir le corps des operations de base effectuee sur un "concept" et non pas sur un type precis.

    ainsi l'utilisation d'un trait pour un "simple" typedef n'apporte pas grand chose, pur avoir une meilleur vision des capacite des traits regarde le code de la std::string

    edit : je me suis mal exprimer, disons qu'un trait fourni une "interface" sur un concept (des char, des stream, etc). la specialization du trait pour un type donne fourni le corps des methods pour chacun des types du concept
    (jme suis peut etre encore mal exprimer la )

  3. #3
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Pour reprendre un peu ce que dok3 t'expliquait, une classe de traits n'a pour but que de fournir des caractéristiques sur un type donné, tout en restant conforme a une certaine interface qui permettra d'utiliser ton trait là où il est attendu.

    Petit exemple avec numeric_limits par exemple, qui fonctionne plus ou moins de cette manière :

    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
    template <typename T> struct numeric_limits;
     
    template <> struct numeric_limits<float>
    {
        static float max() {return FLT_MAX;}
        enum {IsIntegral = 0};
    };
     
    template <> struct numeric_limits<int>
    {
        static int max() {return INT_MAX;}
        enum {IsIntegral = 1};
    };
     
    // ...
     
    template <typename T>
    void Fonction(T x)
    {
        if (x < numeric_limits<T>::max())
            cout << "Blah blah" << endl;
     
        if (numeric_limits<T>::IsIntegral)
            cout << "Blah blah" << endl;
    }

  4. #4
    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
    Imagine que tu ait une classe que tu ne peux pas modifier, et qui ait un typedef sur la donnée nommé "Type" et non pas "type". Ou même que ton Conteneur soit un type de base, genre int. Tu seras alors bien content de pouvoir lui ajouter en externe l'information nécessaire pour le faire entrer dans ton framework.
    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.

  5. #5
    Membre expert
    Inscrit en
    Janvier 2005
    Messages
    2 291
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 291
    Points : 3 212
    Points
    3 212
    Par défaut Traits again
    Rebonjour tout le monde;

    Merci pour vos réponses déjà je crois que je comprends à peu près ce que vous voulez dire. Cependant l'exemple de numerics_limits indique une specialisation des classes.

    Si on prend l'exemple de la classe graph_traits de Boost :
    http://www.boost.org/libs/graph/doc/graph_traits.html

    Il semble qu'ils définissent simplement les types des sommets, des arcs, ou des itérateurs sur les structures en ne faisant que des typedef typename Graph::type type;

    Dans ce cas, quelle est la différence entre cette méthode et le fait de faire directement Graphe::type type; dans notre algorithme? Puisque de toute facon il faudra faire quand meme graph_traits<Graphe>::type type; si on utilise les traits!

    Merci!

  6. #6
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Si un jour tu souhaites utiliser une autre classe de graphe qui définit les mêmes concepts mais pas avec les mêmes noms, tu pourras alors faire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template <>
    struct graph_traits<MyGraph>
    {
        typedef typename MyGraph::VertexDescriptor   vertex_descriptor;
        typedef typename MyGraph::EdgeDescriptor     edge_descriptor;
        typedef typename MyGraph::AdjacencyIterator  adjacency_iterator;
        typedef typename MyGraph::OutEdgeIterator    out_edge_iterator;
        // ...
    };
    L'interêt des traits n'est pas d'être utilisé tel quel, mais d'être spécialisé pour adapter un type particulier à un framework existant.

  7. #7
    Membre expert
    Inscrit en
    Janvier 2005
    Messages
    2 291
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 291
    Points : 3 212
    Points
    3 212
    Par défaut Traits end
    Ok je crois que j'ai compris.

    Merci en tout cas!

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

Discussions similaires

  1. Class de traits ou préprocessor ?
    Par jblecanard dans le forum C++
    Réponses: 7
    Dernier message: 03/01/2011, 11h08
  2. Réponses: 2
    Dernier message: 26/11/2010, 00h10
  3. Probleme avec une class qui traite la date
    Par tarikmahf dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 10/11/2008, 22h12
  4. [C#]Classe, comment accéder au conteneur
    Par nerillis dans le forum Windows Forms
    Réponses: 5
    Dernier message: 01/10/2008, 16h57
  5. classe de trait
    Par poukill dans le forum C++
    Réponses: 4
    Dernier message: 21/08/2007, 15h40

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