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 :

Hack const --> non const ?


Sujet :

C++

  1. #1
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut Hack const --> non const ?

    J'expose mon problème:

    je dispose de 2 set de int :
    -l'un est un paramètre de ma fonction passer en référence constante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void a_function(const set<int> &my_set_const)
    - l'autre est local à ma fonction et est bien sur non const:
    Pour les besoins d'un algo je dois faire un tableau de 2 éléments contenant les adresses vers ces deux sets.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    set<int>* local_tab[2]={&my_set_const,&my_local_set};
    J'obtient ici une erreur à l'initialisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    error C2440: 'initializing' : cannot convert from 'const class std::set<int,std::less<int>,class std::allocator<int> > *' 
    to 'class std::set<int,std::less<int>,class std::allocator<int> > *'
    No constructor could take the source type, or constructor overload resolution was ambiguous
    La question est donc comment réussir cette initialisation sachant que si j'ai créé ce tableau c'est pour ne pas avoir à créer de copie du set passé en paramètre.
    J'avais cru entendre parler d'un hack à ce sujet mais je n'arrive plus à le trouver.
    Merci de votre éclairage

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Citation Envoyé par befalimpertinent
    set<int> local_tab[2]
    Ce type stockera des copies.

    Si tu veux des adresses, tu dois utiliser un tableau de pointeurs (const ou non).

    Ensuite, il y a bien un moyen de retirer "plus-ou-moins-pas-trop-salement" l'attribut const d'un pointeur ou d'une référence, mais à part en de rares cas (comme pour éviter la duplication d'un long code dans la surcharge const/non-const d'une fonction membre), il indique que quelque chose ne vas pas:
    1. soit une bibliothèque qui ne modifie rien, mais dont l'interface est mal déclarée (là, il faudra bien utiliser ledit moyen si l'on ne peut modifier la lib)
    2. soit une mauvaise conception.


    Si c'est toi qui développe l'algorithme, tu peux résoudre le cas 1 à la racine.
    Sinon, soit ton algorithme ne modifie pas le set et doit donc utiliser des pointeurs/références const, soit tu dois bosser sur une copie du set. Il n'y a pas vraiment d'alternative propre.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    J'ai rectifier pour le tableau de pointeurs. Le message d'erreur ne concerne plus que le const/ non-const.

    c'est bien moi qui développe l'algorithme et je ne modifie pas le set.

    La raison pour laquelle je souhaite créer ce tableau est plus une raison technique de factorisation de code.

    Je dois effectuer à peu près le même traitement sur ces 2 sets.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int i;
    for(i=0;i<2;i++)
    {
       set<int> &current_set=local_tab[i];
       //Do treatment
       //...
    }
    et je n'ai pas envie de créer un fonction qui ne servirait que dans ce problème précis.

    Ensuite, il y a bien un moyen de retirer "plus-ou-moins-pas-trop-salement" l'attribut const d'un pointeur ou d'une référence,
    Je suis toujours preneur

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Dans ce cas, pourquoi ton algorithme a-t-il besoin d'une référence non-const vers le set ?
    Es-tu sûr que tu ne peux pas t'en passer ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Dans ce cas, pourquoi ton algorithme a-t-il besoin d'une référence non-const vers le set ?
    Le set local est rempli lors du premier passage dans la boucle donc je ne peux pas le mettre en référence const.

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    J'ai du mal à comprendre... Tu appelles deux fois un algorithme qui a deux comportements différents selon le set utilisé ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    J'ai du mal à comprendre... Tu appelles deux fois un algorithme qui a deux comportements différents selon le set utilisé ?
    C'est un peu ça en effet.
    Je comprend que ça ne soit pas forcément très clair.

    Cette boucle à pour fonction de factoriser 2 traitements "casi"-équivalent sur 2 sets différents.

    my_local_set est rempli lors du premier passage de la boucle par des éléments de my_set_const.
    Dans ma boucle de traitement j'ai une condition sur les éléments qui ne n'est valide que pour le premier set.
    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
     
    int i;
    for(i=0;i<2;i++)
    {
       set<int> &current_set=local_tab[i];
       //Do treatment
       set<int>::const_iterator elem;
       for(elem=current_set.begin();elem!=current_set.begin();elem++)
       {
         if(condition(*elem))
           {
             //condition valide que dans le cas du set const
             local_set.insert(*elem);
           }
       }
       //...
    }
    Mais tant pis si il n'est pas possible de passer en non-const le set, je vais en créer une copie locale.

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Es-tu sûr que tu ne peux pas remplir le set local AVANT la partie à factoriser ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    C'est possible en effet mais je risque de perdre un peu l'intérêt de ma factorisation... Enfin pas si sur finalement.
    Je vais y réfléchir.

    Merci

  10. #10
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Solution trouvée !
    En fait j'avais surtout oublier qu'un objet non-const devient plus facilement const que vice-versa.
    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
    void a_function(const set<int> &my_set_const)
    {
    set<int> my_local_set;
    const set<int>* local_tab[2]={&my_set_const,&my_local_set};
    int i;
    for(i=0;i<2;i++)
    {
       set<int> &current_set=local_tab[i];
       //Do treatment
       set<int>::const_iterator elem;
       for(elem=current_set.begin();elem!=current_set.begin();elem++)
       {
         if(condition(*elem))
           {
             //condition valide que dans le cas du set const
             local_set.insert(*elem);
           }
       }
       //...
    }
    }
    De cette façon le pointeur est const mais la variable pointée non et je peux donc faire mes modifications sur mon deuxième set

    Manquais pas grand chose

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 217
    Par défaut
    Je crois que ça pourrais t'aider plus tard: http://cpp.developpez.com/faq/cpp/?page=conversions

    const_cast

  12. #12
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    Quel est le sens de mélanger des choses que l'on a le droit de modifier et des choses que l'on n'a pas le droit de modifier ?

    Si dans le mélange on veut extraire des choses pour pouvoir les modifier, pourquoi diable les avoir mélangées ?
    Si dans le mélange, on ne veut rien extraire en vue de modification ... ben ... suffit de déclarer que c'est un mélange de choses non modifiables.

    "const" n'est qu'un qualificateur qui indique que l'on prend une vue en lecture seule sur une donnée.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  13. #13
    Inactif  
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    1 958
    Détails du profil
    Informations personnelles :
    Âge : 60
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Quel est le sens de mélanger des choses que l'on a le droit de modifier et des choses que l'on n'a pas le droit de modifier ?
    [...]
    Je pense que c'est l'algorithme qui est à revoir.

  14. #14
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Quel est le sens de mélanger des choses que l'on a le droit de modifier et des choses que l'on n'a pas le droit de modifier ?
    En temps normal je serais d'accord avec ça.
    Mais là je suis vraiment dans un cas où je cherche ce comportement. En fait au début j'avais deux boucles consécutives casi-similaire, à une condition près, comportant un traitement complexe et couteux. C'est quand j'ai constaté cette duplication de code que je me suis dis que je devrait le factoriser : ma règle :

    Un seul code -> pas de duplication -> élimination des bugs dupliqués -> maintenance facilité


    Seulement le résultat de la première boucle modifie le comportement de la deuxième et le premier ensemble sur lequel est effectué le traitement est const le deuxième non (puisque rempli lors du premier passage).

    Je vous garantit que c'est beaucoup plus propre/optimisé/structuré et plus compréhensible maintenant.

  15. #15
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    Tu appliques ta boucle une première fois sur les modifiables que tu altères, et une seconde fois sur les non modifiables que tu n'altères pas ?
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  16. #16
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Pas vraiment. Le traitement en lui même ne modifie rien.
    Lors du premier passage : le traitement est effectué sur les non-modifiables et le set modifiable est rempli à cet instant.
    Lors du deuxième passage, le traitement s'effectue cette fois sur le set qui vient d'être construit et aucune modification n'a lieu.

Discussions similaires

  1. multi_index_container et non const
    Par mister3957 dans le forum Bibliothèques
    Réponses: 0
    Dernier message: 27/10/2013, 14h51
  2. Réponses: 27
    Dernier message: 16/05/2009, 14h53
  3. const - non const
    Par Ange_blond dans le forum C++
    Réponses: 9
    Dernier message: 09/06/2008, 14h31
  4. Réponses: 7
    Dernier message: 30/08/2007, 14h17
  5. Réponses: 18
    Dernier message: 19/10/2006, 12h02

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