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 :

Constness et std::set::find


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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 Constness et std::set::find
    Bonsoir,

    Petite question, pourquoi est-il impossible de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    bool Account::isOpen(const Account *account)
    {
        if(s_opened.find(account) != s_opened.end())
            return true;
        else
            return false;
    }
    avec s_opened de type std::set<Account*> ?

    iterator find ( const key_type& x ) const; est la signature de set:find() donc normalement il n'y a pas de conversion de const Account* vers Account* puisque find() prend en paramètre un const...

    Quelqu'un pour m'éclairer ? 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
    Les signautres de find sont :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    iterator find(const key_type&);
    const_iterator find(const key_type&);
    Dans ton cas key_type est Account*, et tu lui donne un const Account* &, ces deux types sont-ils identiques ? Testons :
    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
     
    struct A {};
     
    template<class,class> struct same
    { static const bool result = false; };
     
    template<class T> struct same<T,T>
    { static const bool result = true; };
     
    int main()
    {
      typedef A* key_type;
      std::cout << same<const key_type&, const A* &>::result
    	    << same<const key_type&, A* const &>::result;
      return 0;
    }
    La réponse est donc non.

    Find attend un référence constante sur un pointeur sur Account, et tu lui donne une référence sur un pointeur sur un Account constant. Et on ne peut pas convertir implicitement le second vers le premier.

    Dans ce genre de code je posserais dans la définition de ma classe un typedef sur le type des clés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    typedef typename std::set<Account*>::key_type key_type;
    Et j'utiliserais ce typedef à chaque fois que ce que je veus comme paramètre est une clé. AMA, ca simplifie grandement les choses.

  3. #3
    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
    Merci, je pense avoir compris le problème mais j'ai un peu du mal avec la solution... Puis-je avoir un peu plus de détails ?

    Encore merci

    EDIT : Je peux utiliser un const cast dans ce cas là ?

  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
    Pas besoin de const_cast :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct Account
    {
      typedef typename std::set<Account*>::key_type key_type;
      bool Account::isOpen(const key_type&);
    };
    Après on pourrait se poser la question de la pertinance de passer une référence constante à la place d'une copie (puisqu'ici la taille de ce qui est passé est probablement la même). On pourrait donc aussi faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    bool Account::isOpen(key_type);

  5. #5
    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
    Wicked !
    Merci, je vais tenter ça demain parce que le problème est récurrent et j'ai un peu le cerveau en mélasse là

  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
    Je viens de tester la solution mais je me rend compte que je ne conserve pas le caractère const de l'objet pointé avec cette solution.
    Seul le pointeur reste constant...

    Je voudrais garantir à l'utilisateur (parce que c'est le cas) que le caractère const de l'objet Account existe lors de l'utilisation de la méthode isOpen()...
    Le caractère ouvert d'un compte se traduit par l'existance d'un pointeur vers ce compte dans un std::set de type <Account*>.

    Donc voilà le problème, je ne souhaite pas utiliser de std::set<const Account*> puisque d'autres méthodes de set doivent renvoyer des Account* mais je veux garantir la constness de l'Account pointé passé en paramètre....

    Une solution alternative ?

  7. #7
    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
    J'utilise finalement un const_cast, c'est surtout la seule façon de conserver la signature const Account* et donc de maintenir une certaine logique.

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

Discussions similaires

  1. std::set, find retourne n'importe quoi.
    Par darkman19320 dans le forum C++
    Réponses: 6
    Dernier message: 18/01/2012, 11h40
  2. std::set et find()
    Par Harooold dans le forum SL & STL
    Réponses: 1
    Dernier message: 04/01/2009, 16h25
  3. find() de std::set avec fonction de comparaison
    Par Biglo dans le forum SL & STL
    Réponses: 3
    Dernier message: 13/01/2006, 08h50
  4. Recherche "étoilée" avec std::set
    Par guejo dans le forum MFC
    Réponses: 2
    Dernier message: 06/05/2004, 13h28
  5. STL : std::set problème avec insert ...
    Par Big K. dans le forum MFC
    Réponses: 13
    Dernier message: 08/11/2003, 01h02

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