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 :

Type erasure et accesseurs


Sujet :

Langage C++

  1. #21
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par coda_blank Voir le message
    il faudrait donc hard-coder les format de vertex dans les policy, et ce pour chaque policy particulière ? donc l'utilisateur ne peut définir aucun format de vertex ? ou bien alors c'est lui qui définit sa propre policy ? (je suis pas un aigle sur le pattern strategy, dsl)
    Non, tu ne code que les structures (en veillant à les garder génériques) qui t'intéressent, parce que, si ta classe vertex (par exemple) est composée de trois valeurs nécessaires pour représenter une coordonnée + 1 valeur nécessaire pour représenter la couleur, tu n'a, à peu de chose près, absolument aucun besoin de savoir si elles manipuleront des int, des char, des float ou des double: tu dois juste savoir que la structure est composées de quatre attributs, dont trois sont de type identique.

    Par la suite, c'est à l'utilisateur de décider quel type seront effectivement utilisés pour ces attributs, même si tu peux prévoir toi-même des alias de types pour les combinaisons "les plus plausibles"
    donc carrément définir le type du vertexbuffer à l'avance dans la policy ?
    Cela peut parfaitement s'envisager, à partir du moment où un vertex buffer n'est en définitive qu'un tableau de vertices particulier
    bon, mettons

    maintenant je veux stocker un ensemble de vertexbuffer dans une map

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    map<string, VertexBuffer<T> >
     
    template<T>
    class VertexBuffer{
     
          private : 
     
               //membres divers
     
               vector<T> buffer; //?
     
    }
    je dois tous les spécifier avec le même format de vertex ?
    oui, effectivement, mais cela te convient parfaitemen
    je ne peux pas regrouper des buffers contenant des formats différents au sein d'une même collection ?
    Pourquoi voudrais tu le faire

    Si tu dois manipuler des vertices dans lesquels les coordonnées sont représentées par des double et que tu essaye d'en utiliser dans lesquels les coordonnées sont représentées par des int ou par des float, tu va te retrouver face à des problèmes sans noms

    Il faut bien comprendre que, l'ensemble de ton api est tenu de respecter les même conventions en ce qui concerne les types primitifs manipulés, ne serait-ce que pour s'assurer la cohérence des traitements
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  2. #22
    Membre habitué
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Points : 190
    Points
    190
    Par défaut
    Non, tu ne code que les structures (en veillant à les garder génériques) qui t'intéressent, parce que, si ta classe vertex (par exemple) est composée de trois valeurs nécessaires pour représenter une coordonnée + 1 valeur nécessaire pour représenter la couleur, tu n'a, à peu de chose près, absolument aucun besoin de savoir si elles manipuleront des int, des char, des float ou des double: tu dois juste savoir que la structure est composées de quatre attributs, dont trois sont de type identique.
    alors on a ceci :

    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
     
    struct vertex
    {
        Axis x,y,z;
        Color color;
    };
    template <typename Axis>
    struct position
    {
        Axis x,y,z;
    };
    /*...*/
    template <typename Axis, typename Color /*, autre types nécessaires>
    class Policy
    {
        public:
        typedef typename vertex<Axis, Color> vertex_type;
        typedef typename position<Axis,> position_type;
        /* autres type utilisés */
    };
    et on l'utilise comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef policy<float, unsigned long> policyAxisColor;
     
    policyAxisColor::vertex_type monVertex;
    monVertex.x = 1;
    monVertex.y = 2;
    monVertex.z = 3;
    monVertex.color = 150;
    donc les structures vertex et position sont bien écrites en dur quelque part sans que l'utilisateur puisse en créer de nouvelles; il ne peut en changer que le type
    donc pas d'attributs inconnus à moins de modifer à la mano la classe policy

    Pourquoi voudrais tu le faire
    mettons que je veuille traiter les positions et les couleurs de façons séparées et non plus d'un bloc comme c'est le cas dans vertex_type; j'en crée deux formats différents que je stocke dans deux buffers respectifs

    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
    template <typename Axis>
    struct position
    {
        Axis x,y,z;
    };
     
    template <typename Color>
    struct color
    {
        Color color;
    };
     
    policyAxisColor::position_type myPosition;
    policyAxisColor::color_type myColor;
     
    vector<policyAxisColor::position_type> myPositionsBuffer;
    vector<policyAxisColor::color_type> myColorsBuffer;
     
    //une classe générique pour encapsuler
     
    template<typename T>
    class VertexBuffer{
     
          private :
     
               //infos relatives au buffer
     
               vector<T> buffer;
    }
    je veux simplement stocker ces deux buffers (car il faut bien les stocker ou les référencer qque part) dans une même collection tout en pouvant manipuler les données qu'ils contiennent
    de manière plus générale, je voudrais manipuler une collection d'objets hétérogènes même si ça sonne parfaitement illogique en soi

    Si tu dois manipuler des vertices dans lesquels les coordonnées sont représentées par des double et que tu essaye d'en utiliser dans lesquels les coordonnées sont représentées par des int ou par des float, tu va te retrouver face à des problèmes sans noms
    du moment que je spécifie à l'API les types des données que j'envoie, la taille du buffer et l'emplacement du buffer (via un pointeur), il n'y a pas de problème

  3. #23
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par coda_blank Voir le message
    alors on a ceci :

    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
     
    struct vertex
    {
        Axis x,y,z;
        Color color;
    };
    template <typename Axis>
    struct position
    {
        Axis x,y,z;
    };
    /*...*/
    template <typename Axis, typename Color /*, autre types nécessaires>
    class Policy
    {
        public:
        typedef typename vertex<Axis, Color> vertex_type;
        typedef typename position<Axis,> position_type;
        /* autres type utilisés */
    };
    et on l'utilise comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef policy<float, unsigned long> policyAxisColor;
     
    policyAxisColor::vertex_type monVertex;
    monVertex.x = 1;
    monVertex.y = 2;
    monVertex.z = 3;
    monVertex.color = 150;
    donc les structures vertex et position sont bien écrites en dur quelque part sans que l'utilisateur puisse en créer de nouvelles; il ne peut en changer que le type donc pas d'attributs inconnus à moins de modifer à la mano la classe policy
    En fait la policy sera là pour te donner les "briques de base", et il t'appartient effectivement de veiller à fournir "ce qui sera utile et / ou nécessaire".

    Mais, par la suite, tu restes tout à fait libre, même sans modifier la classe policy, de recourir à l'héritage ou à la composition exactement comme tu peux le souhaiter
    mettons que je veuille traiter les positions et les couleurs de façons séparées et non plus d'un bloc comme c'est le cas dans vertex_type; j'en crée deux formats différents que je stocke dans deux buffers respectifs
    Comme tu n'a pas encore présenté le projet sur lequel tu es, je ne peux dire qu'une chose: c'est à toi d'évaluer les besoins de ton projet, de voir ce que tu dois fournir directement dans policy comme brique de base et à l'utilisateur d'évaluer la manière dont il veut les utiliser ou les regrouper au sein de types plus "concrets"

    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
    template <typename Axis>
    struct position
    {
        Axis x,y,z;
    };
     
    template <typename Color>
    struct color
    {
        Color color;
    };
     
    policyAxisColor::position_type myPosition;
    policyAxisColor::color_type myColor;
     
    vector<policyAxisColor::position_type> myPositionsBuffer;
    vector<policyAxisColor::color_type> myColorsBuffer;
     
    //une classe générique pour encapsuler
     
    template<typename T>
    class VertexBuffer{
     
          private :
     
               //infos relatives au buffer
     
               vector<T> buffer;
    }
    je veux simplement stocker ces deux buffers (car il faut bien les stocker ou les référencer qque part) dans une même collection tout en pouvant manipuler les données qu'ils contiennent
    Dis mois déjà quel avantage tu pourrais trouver à manipuler une collection qui contiendrait à la fois des couleurs et des position...

    Si tu dois effectivement garder une relation entre les deux et avoir une couleur pour chaque position ( à moins que ce ne soit avoir une position pour chaque couleur ) il t'est tout à fait possible de créer une structure qui présente un membre de chaque type, voir même d'utiliser les tuple.

    Mais, de prime abord, l'idée de vouloir mélanger les deux types ne me semble vraiment pas bonne, parce que tu ne peux décemment pas t'attendre à ce qu'une couleur et une position proposent les mêmes services et répondent aux mêmes fonctions: Il n'y a aucun cas dans lequel tu pourrait décider de passer une couleur (ou une position) alors qu'une position (respectivement une couleur) est attendue
    de manière plus générale, je voudrais manipuler une collection d'objets hétérogènes même si ça sonne parfaitement illogique en soi
    L'illogisme ne peut avoir court en informatique parce que la logique est le seul rempart qui puisse te permettre de ne pas te tirer une balle dans le pied.

    Si tu ne respecte pas une logique stricte, comment veux tu que le compilateur comprenne ce que tu attends de lui
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #24
    Membre habitué
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Points : 190
    Points
    190
    Par défaut
    En fait la policy sera là pour te donner les "briques de base", et il t'appartient effectivement de veiller à fournir "ce qui sera utile et / ou nécessaire".

    Mais, par la suite, tu restes tout à fait libre, même sans modifier la classe policy, de recourir à l'héritage ou à la composition exactement comme tu peux le souhaiter
    création de nouveaux formats de vertex => héritage de Policy, ok

    Dis mois déjà quel avantage tu pourrais trouver à manipuler une collection qui contiendrait à la fois des couleurs et des position...
    mais parce qu'il faut bien que je les référence qque part et que je ne vais pas déclarer une liste particulière pour chaque buffer d'un format de vertex quelconque... ce sont tous des VertexBuffers après tout, pas des oranges et des tomates

    le type erasure résolvait partiellement cela mais il pose les problèmes que l'on sait

    voir même d'utiliser les tuple.


    Mais, de prime abord, l'idée de vouloir mélanger les deux types ne me semble vraiment pas bonne, parce que tu ne peux décemment pas t'attendre à ce qu'une couleur et une position proposent les mêmes services et répondent aux mêmes fonctions: Il n'y a aucun cas dans lequel tu pourrait décider de passer une couleur (ou une position) alors qu'une position (respectivement une couleur) est attendue
    mais si la donnée s'accompagne d'informations sur son traitement particulier ?

  5. #25
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par coda_blank Voir le message
    mais parce qu'il faut bien que je les référence qque part
    Cela, je suis d'accord, par contre
    et que je ne vais pas déclarer une liste particulière pour chaque buffer d'un format de vertex quelconque... ce sont tous des VertexBuffers après tout, pas des oranges et des tomates
    Ca, c'est totalement faux...

    Je suis d'accord pour accepter le fait que tu utilise un terme identique pour représenter deux choses différentes, mais, c'est un problème similaire à celui que l'on rencontre lorsqu'il faut définir un type carré et un type rectangle: Du seul point de vue géométrique, on peut dire qu'un carré est un rectangle "un peu particulier" dans le sens où sa longueur et sa largeur sont égales, mais d'un point de vue OO, on ne peut pas faire hériter la classe carré de la classe rectangle parce qu'un tel héritage viole LSP dans le sens où toutes les propriétés valides pour les rectangle ne le sont pas pour un carré (il n'y a aucune logique à permettre de parler de longueur et de largeur pour un carré).

    Dans le cas d'un vertex ou d'un vertex buffer, c'est peut être encore pis dans le sens où l'on remarque qu'ils portent des noms identiques, qu'il présentent des interfaces identiques, mais qu'une propriété primordiale qui fait d'un vertex ce qu'il est n'est pas la même: le type utilisé pour représenter les différentes valeurs.

    le type erasure résolvait partiellement cela mais il pose les problèmes que l'on sait

    voir même d'utiliser les tuple.
    on pourrait parler de std::pair (hé oui, cela peut servir en dehors des map ), en ne considérant simplement pas qu'il y a une clé et une valeur, mais en considérant plutôt qu'il y a, tout simplement, deux valeurs de type différents qui participent à la "définition" d'un objet unique
    mais si la donnée s'accompagne d'informations sur son traitement particulier ?
    Non, parce que cela va décidément à l'encontre du principe de substitution de Liskov (LSP).

    C'est un tout qui se tient de manière inextricable:

    Une couleur, cela n'a rien à voir avec une position ou même avec un vertex.

    Tu ne peux donc absolument pas envisager de les voir apparaitre dans une hiérarchie de classes commune, parce qu'il n'y a même pas une seule propriété commune entre ces deux entités.

    Et donc, tu ne trouvera jamais le moyen, autre que celui de créer un tuple ou une quelconque composition de ces deux entité, susceptible de les faire cohabiter dans une seule et même collection.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #26
    Membre habitué
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Points : 190
    Points
    190
    Par défaut
    Cela, je suis d'accord, par contre
    et vous avez une idée de comment les référencer autrement que par conteneur ? un pattern maya secret p-e ?

    Ca, c'est totalement faux...
    ...
    Et donc, tu ne trouvera jamais le moyen, autre que celui de créer un tuple ou une quelconque composition de ces deux entité, susceptible de les faire cohabiter dans une seule et même collection.
    je crois que j'ai compris la leçon

    finalement le type-erasure c'est un gros hack en somme...

    que dites-vous de Boost.Any ?

  7. #27
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par coda_blank Voir le message
    et vous avez une idée de comment les référencer autrement que par conteneur ? un pattern maya secret p-e ?
    Je dis que je suis effectivement d'accord qu'il faudra sans doute utiliser des conteneurs pour les référencer quelque part, mais, sans doute, au moins deux instances de conteneurs contenant sans doute chacun des objets différents.
    finalement le type-erasure c'est un gros hack en somme...
    Non, absolument pas...

    Le type-erasure est parfaitement justifié dans bien des situations, à condition de respecter les autres principes de base
    que dites-vous de Boost.Any ?
    Je suis personnellement mitigé sur l'utilisation de boost.any.

    Comme souvent en programmation, c'est quelque chose qui peut s'avérer extrêmement utile, mais qui ne doit pas être utilisé n'importe comment ni pour n'importe quelle raison

    La grosse difficulté consistant à déterminer exactement quand c'est la moins mauvaise solution à apporter à un problème donné
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #28
    Membre habitué
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Points : 190
    Points
    190
    Par défaut
    Je dis que je suis effectivement d'accord qu'il faudra sans doute utiliser des conteneurs pour les référencer quelque part, mais, sans doute, au moins deux instances de conteneurs contenant sans doute chacun des objets différents
    et bien sûr comment référencer ces conteneurs; en dur je suppose ?

Discussions similaires

  1. Contourner le Type Erasure des collections
    Par scheme dans le forum Langage
    Réponses: 4
    Dernier message: 18/02/2011, 16h00
  2. Réponses: 29
    Dernier message: 20/09/2009, 06h27
  3. utilisation du meta type ANY
    Par Anonymous dans le forum CORBA
    Réponses: 1
    Dernier message: 15/04/2002, 12h36

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