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 :

error: passing 'const A' as 'this' argument of 'bool A::operator<(const A&)' discards qualifiers


Sujet :

Langage C++

  1. #1
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut error: passing 'const A' as 'this' argument of 'bool A::operator<(const A&)' discards qualifiers
    Bonjour,

    j'ai voulu faire des tests (en attendant qu'une compil' de 3h termine ) sur les fonctions de tri, et les différentes écritures pour voir si à la fin il y allait avoir une grosse différence entre telle ou telle méthode sur le plan des performances.

    Le code est encore en chantier mais je n'ai de toute façon pas eu le temps de finir avant de tomber sur une erreur :

    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 <iostream>
    #include <vector>
    #include <list>
    #include <algorithm>
    #include <chrono>
     
    class A
    {
        int z;
     
        public:
            A(const int& z) : z(z){}
            const int& getZ() const { return z; }
            bool operator< (const A& a) { return getZ() < a.getZ();}
    };
     
    using namespace std;
     
    int main()
    {
        vector<A> v = { A(1), A(3), A(2), A(4),A(5) };
        list<A> l = { A(1), A(3), A(2), A(4), A(5) };
     
        //tests with vector
        sort(v.begin(), v.end()); //operator<
     
        sort(begin(v),end(v)); //operator<
     
        sort(v.begin(), v.end(), less<A>());
     
        sort(begin(v), end(v), less<A>());
     
        sort(begin(v), end(v), [](const A& a, const A& b){ return a.getZ() < b.getZ(); });
     
        //tests with list
        l.sort(); //operator<
     
        return 0;
    }
    Si j'ai bien compris, mon opérateur de comparaison en tant que fonction membre utilise this (qui est de type A* non ?) comme un const A, ce qui fait que la deuxième opérande pour ma comparaison n'est pas au format attendu par std::sort (const A&).

    Ma question est : quelles sont les erreurs dans mon code ? Il se passe plusieurs choses entre l'utilisation de this et la découverte d'une opérande de type const A : quelqu'un pourrait-il me l'expliquer de la manière la plus complète possible (si je ne suis pas HS) ?

    Autre question : j'ai voulu mettre z() comme accesseur et le compilo n'accepte pas (pourtant j'étais persuadé d'avoir toujours fait des trucs du style private int x; public const int x() const {return x;}). Suis-je en train de me craquer ou devrais-je pouvoir appeler ma fonction comme ceci ?
    Nullius in verba

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    En tant que fonction membre, l’opérateur < doit être const

    Et pour le coup de l'accesseur, on, il faut un nom différent.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Ok, ça manque un peu d'explication, mais au moins ça compile... pour le coup si quelqu'un se sent de donner un peu plus d'information je n'y serai pas contre
    Nullius in verba

  4. #4
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    L'appel à sort sans fournir de prédicat doit faire appel a std::less(*), qui réalise x<y ce équivaut à x.operator<(y).

    les arguments de std::less sont passés par référence constante. Et sur un objet constant, on ne peut appeler que des méthodes const.

    D’oùla nécessité de la constance de l’opérateur < en tant que fonction membre.

    Avec une fonction libre, pas de soucis de ce genre à se poser.
    De plus, je trouve la sémantique de operator< plus clair en tant que fonction libe.

    * : supposition à cet endroit
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    R T::operator <(S b);
    Dans ton lien habituel, en tant que fonction membre on ne précise pas qu'elle doit être const pour être utilisable par certaines fonctions de la STL.
    Nullius in verba

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Parce que c'est la STL qui oblige la méthode à être const.
    Si demain une lib décide d'utiliser des paramètres non const dans une opération <, l'opérateur n'aura pas besoin d'être const.
    C'est donc tout à fait normal et logique.

    Quand on utilise une lib, on s'en tient à la doc de la lib et on s'y adapte, fusse-t-elle la STL.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Je n'ai pas dit le contraire, juste que je ne vois pas l'utilité de fournir ce lien puisque ce n'était pas le propos... je ne voulais que te faire remarquer que de fournir un lien vers les prototypes des opérateurs ne m'apportais strictement rien puisque c'est exactement ce que j'avais fait avant de poster un message ici.

    Et puis je ne partage pas ton avis. La librairie standard peut avoir un traitement particulier par sa nature.

    Enfin, si l'ensemble avait peut-être été lu de façon un peu plus complète, j'aurais pu avoir un lien plus utile que le tiens, car mon questionnement initial (qui n'a toujours pas trouvé de réponse complète (*)) était tout autre.

    Cependant merci à Davidbrcz d'avoir fait un effort supplémentaire pour répondre de façon plus étayée.

    (*) Je n'ai pas encore compris pourquoi this qui est ici un pointeur non-const sur A se retrouve en argument de std::less comme un const A (d'après ce que je comprends du message du compilateur)... peut-être un lien avec ce que renvoie operator-> appliqué à this ? je ne sais vraiment pas ce qui se passe... <= j'aprécierais une explication détaillée, si quelqu'un sait, afin de mieux comprendre le cheminement du compilateur "sous le capot", ou une explication aboutie sur mon erreur de raisonnement dans cette affirmation.
    Nullius in verba

  9. #9
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Kaamui Voir le message
    (*) Je n'ai pas encore compris pourquoi this qui est ici un pointeur non-const sur A se retrouve en argument de std::less comme un const A (d'après ce que je comprends du message du compilateur)... peut-être un lien avec ce que renvoie operator-> appliqué à this ? je ne sais vraiment pas ce qui se passe... <= j'aprécierais une explication détaillée, si quelqu'un sait, afin de mieux comprendre le cheminement du compilateur "sous le capot", ou une explication aboutie sur mon erreur de raisonnement dans cette affirmation.
    C'est sort qui appelle less<> qui tente d'appeller operator< mais ne peut pas parce que les arguments de less<> sont const.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    http://lmgtfy.com/?q=std%3A%3Aless : premier lien : http://www.cplusplus.com/reference/functional/less/

    Tu utilises std::less, cherche donc la doc de std::less
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

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

Discussions similaires

  1. [2.x] Formulaire: Catchable Fatal Error: Argument 1 passed to
    Par oukacha dans le forum Symfony
    Réponses: 2
    Dernier message: 02/05/2012, 19h36
  2. Réponses: 20
    Dernier message: 16/11/2009, 23h04
  3. Réponses: 3
    Dernier message: 02/01/2009, 12h25
  4. Réponses: 2
    Dernier message: 20/02/2008, 14h32
  5. const Point & et this
    Par vincho dans le forum C++
    Réponses: 9
    Dernier message: 01/03/2007, 17h45

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