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 :

Eviter un const_cast dans un foncteur


Sujet :

SL & STL C++

  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Par défaut Eviter un const_cast dans un foncteur
    J'ai un pb tres simple, je veux tranformer un const vector<T> en un vector<T*>.
    Voici un extrait de mon code qui le fait :

    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
        template<typename T>
        struct ToPtr : public std::unary_function<T, T*>
        {
            T* operator()(const T& value)
            {
                return const_cast<T*>(&value);
            }            
        };
     
    template<typename T>
        void MyClass::order(const vector<T>& in,
                            vector<T*>& out) const
        {
     
                out.reserve(in.size());
                std::transform(in.begin(),
                                   in.end(),
                                   std::back_inserter(out),
                                   ToPtr<T>());
    }
    Ce code marche tres bien mais ce qui me gene c'est le const_cast dans le foncteur. Est - ce qu'il existe une meilleure conception pour convertir un const vector<T> en vector<T*> ?

  2. #2
    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 : 50
    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
    Par défaut
    Tu as un vector<T> const, donc une variable à partir de laquelle tu promets de ne pas modifier le contenu du vecteur. Tu veux obtenir un vector<T*>, qui permet donc de modifier les T contenue dans le premier vecteur.

    Il me semble donc normal que tu aies besoin d'un const_cast, puisque tu souhaites ne pas permettre la modification d'objets constants.

    Ton code est moralement équivalent à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int const i = 3;
    int *j = &i;
    La vrai question est pourquoi tu souhaites faire ça...
    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.

  3. #3
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Par défaut
    Simplement parce que T est un tres gros type et que je veux trier les elements du vecteur. Donc je passe par un vecteur de T* qui sera beaucoup plus rapide a trier qu'un vecteur de T .
    Mais si tu as une autre solution, je suis preneur.

  4. #4
    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
    Citation Envoyé par vandamme Voir le message
    Simplement parce que T est un tres gros type et que je veux trier les elements du vecteur. Donc je passe par un vecteur de T* qui sera beaucoup plus rapide a trier qu'un vecteur de T .
    Mais si tu as une autre solution, je suis preneur.
    Qu'est ce qui te fait penser que le T* sera plus rapide à trier que le T&

    Si tu veux trier les ardresses, peut etre, mais autrement, je n'en suis pas sur du tout
    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

  5. #5
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Qu'est ce qui te fait penser que le T* sera plus rapide à trier que le T&
    Les nombreuses recopies induites par le tri.

    Mais si tu as une autre solution, je suis preneur.
    Transforme en vector<const T*>, tu n'auras pas besoin de casser le const.

  6. #6
    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
    Citation Envoyé par Laurent Gomila Voir le message
    Les nombreuses recopies induites par le tri.
    Ah oui, je n'y avais pas pensé, à celles là
    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

  7. #7
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Par défaut
    Citation Envoyé par Laurent Gomila Voir le message
    Les nombreuses recopies induites par le tri.


    Transforme en vector<const T*>, tu n'auras pas besoin de casser le const.
    OK. j'essaierai cette solution. En fait je pensais que const vector<T*> etait equivalent a vector<const T*>.

    Par contre une autre idee me vient pour le tri.
    Est ce qu'en utilisant une list au lieu d'un vector, et en particulier sa fonction membre sort, je peux eviter les recopies lors du tri ?

  8. #8
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Par contre une autre idee me vient pour le tri.
    Est ce qu'en utilisant une list au lieu d'un vector, et en particulier sa fonction membre sort, je peux eviter les recopies lors du tri ?
    Carrément pas. Comment veux-tu ordonner les éléments sans les déplacer (ie. les recopier) ? En plus, le tri sur std::list sera encore plus lent du fait que ses itérateurs ne sont pas à accès aléatoire.

  9. #9
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Par défaut
    Citation Envoyé par Laurent Gomila Voir le message
    Carrément pas. Comment veux-tu ordonner les éléments sans les déplacer (ie. les recopier) ? En plus, le tri sur std::list sera encore plus lent du fait que ses itérateurs ne sont pas à accès aléatoire.
    Ah d'accord.
    Je pensais en fait que un node dans une liste etait compose d'un element T et d'un pointeur vers le suivant et/ou le precedent T. Et je pensais que seul le pointeur etait modifie pdt le tri mais que les elements n'etaient pas inpactes.

  10. #10
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Je pensais en fait que un node dans une liste etait compose d'un element T et d'un pointeur vers le suivant et/ou le precedent T. Et je pensais que seul le pointeur etait modifie pdt le tri mais que les elements n'etaient pas inpactes.
    En fait... oui (faut vraiment plus que je réponde avant d'avoir bu mon café du matin)

  11. #11
    screetch
    Invité(e)
    Par défaut
    std::sort ne marche que sur les iterateurs a acces aleatoire, donc pas sur les listes, ce qui resout le probleme

    en revanche std::list a une fonction sort()

    exemple :

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #include <vector>
    #include <list>
    #include <algorithm>
     
    static int numCopies;
    static int numAffectations;
     
    struct StructureATrier
    {
    	int m_value;
    	StructureATrier(int value) :
    		m_value(value)
    	{}
    	StructureATrier(const StructureATrier& other) :
    		m_value(other.m_value)
    	{ numCopies++; }
    	StructureATrier& operator=(const StructureATrier& other)
    	{ m_value = other.m_value;  numAffectations++;  return *this; }
    };
     
    bool operator<(const StructureATrier& _Left, const StructureATrier& _Right)
    { return _Left.m_value < _Right.m_value; }
     
     
    int main(int argc, char** argv)
    {
    	std::vector< StructureATrier > v;
    	std::list< StructureATrier > l;
    	for(int i = 72; i >= 0; --i)
    	{
    		v.push_back(StructureATrier(i));
    		l.push_back(StructureATrier(i));
    	}
    	numCopies = numAffectations = 0;
    	std::sort(v.begin(), v.end());
    	printf("vector : %d copies, %d affectations\n", numCopies, numAffectations);
    	numCopies = numAffectations = 0;
    	l.sort();
    	printf("list : %d copies, %d affectations\n", numCopies, numAffectations);
    }
    Resultat instructif, surtout pour ceux qui ont pas pris le café ^^

  12. #12
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Par défaut
    Oui tout a fait.
    D'ailleurs je parlais bien de la fonction membre sort de list et non pas de l'algo standard

  13. #13
    screetch
    Invité(e)
    Par défaut
    trier une liste a la meme complexite algorithmique que trier un vector mais evite les copies. Les insertions au milieu sont plus rapides, mais tout depend de la taille.

    Si tu vas traiter 50 elements tu ne verras meme pas la difference ^^

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

Discussions similaires

  1. Comment eviter les doubons dans une requête?
    Par jyms2006 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 08/03/2006, 14h08
  2. comment eviter des doublons dans un sous formulaire ??
    Par azde7015 dans le forum Access
    Réponses: 2
    Dernier message: 21/02/2006, 09h03
  3. [HTML] Eviter la censure dans une infobulle (forum phpbb)
    Par Angkorr dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 25/01/2006, 17h53
  4. Eviter plusieurs OR dans une requete SELECT
    Par zoubidaman dans le forum Requêtes
    Réponses: 2
    Dernier message: 13/06/2004, 05h56

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