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

SL & STL C++ Discussion :

Cast de set<A> vers set<B> quand A hérite de B


Sujet :

SL & STL C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 96
    Par défaut Cast de set<A> vers set<B> quand A hérite de B
    Tout est dans le titre...

    J'ai besoin de caster de set<A> vers set<B> quand A hérite de B.
    Il est donc impossible de d'écrire la méthode membre de cast qui réalise cette tâche (dans std::set)

    La STL permet cette gymnastique ? Ou faut-il que j'écrive une fonction.

    Merci

  2. #2
    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
    Si tu connais le fonctionnement des algos de la STL (avec les itérateurs) regardes les différents algos. (En oubliant pas que pour un set ce sont des itérateurs constants)

    Comme ca j'utiliserais un for_each un static_cast dans un lambda (ou dynamic_casts elon à quoi c'est destiné), quelque chose comme :
    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
     
    template<class T, class InputIterator>
    std::set<T> set_static_cast(InputIterator first, InputIterator last)
    {
      std::set<T> s;
      typedef typename InputIterator::value_type value_type;
      std::for_each(first,last,[&](const value_type& v)
        {s.insert(static_cast<T>(v));});
      return s;
    }
     
    //Utilisation
    std::set<char> s1;
    std::set<int> s2 = set_static_cast<int>(s1.begin(),s1.end());
    //Marche avec tes classes si elles sont faites pour aller dans un set

  3. #3
    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
    Par défaut
    La conversion de la classe dérivée vers la classe de base est implicite, donc en se basant sur le constructeur avec itérateur cela devrait suffire non ?:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct B
    {
    };
     
    struct A : public B
    {
    };
     
        std::set<A> set_a;
     
        std::set<B> set_b(set_a.begin(),set_a.end());


    Ceci dit, une classe propice à l'héritage porte en général une sémantique d'entité. Ce qui se marie assez mal avec la copie. Copie qui traverse ta question par au moins 2 points : le fait d'avoir un conteneur par valeur (std::set<A>) et non par pointeur (std::set<std::shared_ptr<A>>) et le fait de faire une copie de A vers B.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 96
    Par défaut
    En d'autres termes il serait plus judicieux de faire un set de pointeurs et à cause de la sémantique d'entité de ma classe.
    Ok je pense que je vois ce que tu veux dire.

    Merci

  5. #5
    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
    Par défaut
    Citation Envoyé par Agoudard Voir le message
    En d'autres termes il serait plus judicieux de faire un set de pointeurs et à cause de la sémantique d'entité de ma classe.
    Ok je pense que je vois ce que tu veux dire.
    Probablement. Pense à construire un prédicat pour la comparaison sinon elle risque de se faire sur l'adresse. Ensuite => smart ptr

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 96
    Par défaut
    Pourquoi c'est un problème d'avoir l'adresse pour la comparaison ? l'adresse d'un objet est unique non ?

  7. #7
    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
    Par défaut
    Hum, je me suis mail exprimé.

    Ce n'est pas forcément un problème et effectivement elle va être unique. C'est plutôt à toi de voir ce qui est plus pertinent pour caractériser l'élément de ton set. L'adresse peut être un critère pertinent ou pas. Faut juste savoir que ce sera là dessus que le tri se fera par défaut

  8. #8
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    A vrai dire, je ne vois pas vraiment pourquoi tu voudrais caster un set de A en un set de B si c'est A qui hérite de B : tout objet de type a pouvant sans aucun problème être utilisé par toute fonction prenant un objet de type B (sous la forme d'une référence (éventuellement constante) ou d'un pointeur) comme argument.

    Pire encore: le fait de créer une nouvelle instance de B (la classe est-elle seulement instanciable ) au départ d'une instance de A a de fortes chances de provoquer des pertes de données: tout membre spécifique au type A ne sera pas pris en compte et donc considéré comme perdu dans le nouveau B utilisé

    Si tu veux créer un set contenant des variables de plusieurs types différents héritant tous de B, il faudra effectivement utiliser un set de pointeur, ce qui me fait rebondir sur la remarque de 3DArchi :

    Typiquement, les classes dérivées ont ce que l'on appelle une sémantique d'entité (ainsi qu'il a déjà été signalé).

    Cela n'empêche que l'on puisse vouloir être en mesure d'en trier les différentes instances sur autre chose que sur leur adresse, car la sémantique d'entité n'exclu absolument pas la notion d'identifiant unique pour chaque instance.

    Afin de me faire comprendre, prenons le cas d'une classe "Employe", qui hérite d'une classe Personne.

    La classe Personne et la classe Employe ont clairement sémantique d'entité car chaque instance de Personne ou d'Employe représente bel et bien une personne (physique) unique et clairement identifiable.

    Mais, pour être en mesure d'identifier de manière unique et non ambigue chaque personne, il va falloir se baser sur... une ou plusieurs propriétés qui prises ensemble (s'il y a plusieurs propriétés) permettront de s'assurer que l'on parle bien de Gerard Lambert, de la comptabilité, et non du Gerard Lambert, chieur de première, du service courrier (toutes mes excuses à tous les gérard lambert ).

    De même, on souhaitera sans doute, pour notre propre facilité, être en mesure de retrouver les différents employés dans un ordre bien précis : il est plus facile de s'y retrouver s'il s'ont triés par leur nom puis leur prénom (et autres critères éventuels), que s'ils apparaissent dans un ordre impossible à déterminer car dépendant des conditions d'exécution même de l'appliction.

    Ce sont, d'ailleurs, ces critères qui permettront, bien plus que l'adresse mémoire à laquelle se trouve l'instance, de déterminer de manière claire et non ambigüe si, oui ou non, nous avons bel et bien affaire à "la même personne" ou si, au contraire il s'agit de "quelqu'un d'autre".

    C'est dans ce cadre, et pour que le tri soit cohérent, qu'il est fortement préférable de prévoir un (prédicat) moyen permettant de comparer efficacement les différentes instances de ta classe
    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

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

Discussions similaires

  1. Réponses: 25
    Dernier message: 11/08/2010, 15h54
  2. Rediriger vers une page de login quand timeout de session
    Par Tail dans le forum Servlets/JSP
    Réponses: 9
    Dernier message: 18/09/2008, 12h43
  3. Réponses: 3
    Dernier message: 06/12/2007, 15h15
  4. Réponses: 11
    Dernier message: 30/10/2007, 09h35
  5. Mauvais cast de Set
    Par LorDjidane dans le forum Collection et Stream
    Réponses: 6
    Dernier message: 08/11/2006, 17h40

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