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 :

probleme avec std::find


Sujet :

C++

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 274
    Points : 56
    Points
    56
    Par défaut probleme avec std::find
    Bonjour à tous,
    voila je viens de voir un peu comment fonctionner les iterators et les lambda et j'ai voulu m'entrainer un peu. Mais voila je coince. Je vous montre mon code:
    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
    #include <iostream>
    #include <vector>
    #include <algorithm>
    class A
    {
     
    public:
    	A(int value = 0): m_value(value) {};
     
    	int m_value;
     
    }; 
     
     
    int main()
    {
     
    	std::vector<A> tab(10);
     
    	(*(tab.begin() + 5)).m_value = 66;
     
     
    	auto it = std::find(tab.begin(), tab.end(), [](A &a){
    		if( a.m_value == 66)
    		{
    			std::cout << "yes" << std::endl;
    			return true;
    		}
    		else
    		{
    			return false;
    		}
    	});
     
    	std::cout <<  it->m_value << std::endl;
     
    	return 0;
    }
    le probleme est lorsque je compile mon code ca me retourne l'erreur :
    /usr/include/c++/8/bits/predefined_ops.h:241:17: error: no match for ‘operator==’ (operand types are ‘A’ and ‘const main()::<lambda(A&)>’)
    { return *__it == _M_value; }
    je ne comprends pas du tout l'erreur qu'il me retourne. Le compilateur me parle de operator== alors que je ne vois aucun problème.

    Merci d'avance pour votre aide

  2. #2
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 696
    Points : 2 435
    Points
    2 435
    Par défaut
    Bonjour.

    std::find doit pouvoir comparer deux objets, pour cela la classe doit indiquer comment le faire avec l'opérateur ==, qui n'est pas présent dans la classe A (d'où l'erreur).

    Il suffit donc d'implémenter l'opérateur dans A.
    Je fais appel aux esprits de Ritchie, Kernighan, Stroustrup et Alexandrescu
    Donnez moi la force, donnez moi le courage de coder proprement !

    « Ça marche pas » n'est PAS une réponse convenable, merci de détailler le souci en fournissant l’environnement, le code source, les commandes et les messages d'erreur.

    Ce club possède également un clavardage, on y trouve quelques perles entre deux sessions d'entraides.

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par Daïmanu Voir le message
    Il suffit donc d'implémenter l'opérateur dans A.
    Ou, à tout le moins, pour A...

    Ce serait difficilement applicable dans le cas présent (à moins de définir l'opérateur == comme étant une fonction amie de A), mais une fonction libre dont le prototype ressemble à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    bool operator == (A const & a, A const & b){
        /* ... */
    }
    fonctionnerait au moins aussi bien que l'opérateur sous forme de fonction membre, et présenterait en outre moins de restrictions
    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

  4. #4
    Membre du Club
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 274
    Points : 56
    Points
    56
    Par défaut
    Merci pour vos réponses
    donc je peux trouver des objets uniquement en créant l'opérateur== ? ca me parait moyen comme méthode car une fois l'operator== implémenté, je ne peux plus rien changer, et si je veux trouver des objets avec des caractéristiques différents je dois de nouveau changer l'operator==. il n' y pas moyen de mettre des predikas ou des lambdas ?

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Tu peux, avec std::find_if.

  6. #6
    Membre actif Avatar de BioKore
    Homme Profil pro
    Dresseur d'Alpaga
    Inscrit en
    Septembre 2016
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Dresseur d'Alpaga

    Informations forums :
    Inscription : Septembre 2016
    Messages : 300
    Points : 219
    Points
    219
    Par défaut
    Bonjour,

    J'ai fait les tests et... il s'avère que l'opérateur == n'est pas le seul élément en cause ici.
    Globalement, std::find compare les objets d'un conteneur par rapport à un objet quelconque. Je ne vois pas trop ce que vient faire le lambda ici.

    De mon côté, ce code ne fonctionne pas :
    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
    #include <iostream>
    #include <vector>
    #include <algorithm>
     
     
     
    struct Test {
    	Test(int const val=int{}): mValue{val} {};
    	int mValue;
    };
     
    bool operator==(Test const & left, Test const & right) { return left.mValue == right.mValue; }
    bool operator!=(Test const & left, Test const & right) { return !(left==right); }
     
    int main() {
    	std::vector<Test> tab(10, Test{});
     
    	tab[5].mValue = 66;
     
    	auto it{ std::find( tab.begin(), tab.end(), [](Test & obj){ return obj.mValue == 66 ? true : false; }) };
     
    	std::cout << it->mValue << '\n';
     
    	return 0;
     
    }
    Car le compilateur me dit que l'on essaie de comparer un objet de type Test à un objet de type lambda....
    Par contre, si on modifie le std::find par : auto it{ std::find( tab.begin(), tab.end(), Test{66}) };, alors tout roule...

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par BioKore Voir le message
    Globalement, std::find compare les objets d'un conteneur par rapport à un objet quelconque. Je ne vois pas trop ce que vient faire le lambda ici.
    Si la classe utilisée ne possède pas d'opérateur ==, ou que l'on souhaite utiliser un critère de comparaison différent, c'est là qu'elle intervient. Mais pas avec std::find (qui recherche un élément == à l'objet passé en paramètre), avec std::find_if (qui recherche un élément sur lequel le prédicat retourne true).

    En passant return obj.mValue == 66 ? true : false; se simplifie en return obj.mValue == 66; et la lambda ne doit pas modifier les éléments du tableau => [](Test const & obj).
    Et dans un cas « normal » d'utilisation où on ne saura pas si l'élément en question est présent ou non, on commencera par vérifier si it != tab.end() avant de l'utiliser.

  8. #8
    Membre actif Avatar de BioKore
    Homme Profil pro
    Dresseur d'Alpaga
    Inscrit en
    Septembre 2016
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Dresseur d'Alpaga

    Informations forums :
    Inscription : Septembre 2016
    Messages : 300
    Points : 219
    Points
    219
    Par défaut
    Citation Envoyé par Winjerome Voir le message
    std::find_if
    Yes ! Effectivement, ça marche mieux comme ça avec les lambda !
    Quant au ternaire, c'est plus pour garder l'idée générale de la fonction initiale qui faisait intervenir un std::cout au milieux; mais d'accord avec toi, c'est plus rapide avec return obj.mValue==66;.

    Bref, dans tous les cas, si on utilise std::find_if avec la lambda proposée, on a effectivement pas besoin des opérateurs ==. Logique mais intéressant à savoir.

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

Discussions similaires

  1. probleme avec std::list
    Par jahmanzaar dans le forum Débuter
    Réponses: 3
    Dernier message: 19/12/2008, 21h02
  2. [Data] probleme avec getHibernateTemplate.find()
    Par Tauros_king dans le forum Spring
    Réponses: 2
    Dernier message: 22/03/2007, 11h05
  3. Probleme avec std::vector
    Par dhoorens dans le forum SL & STL
    Réponses: 2
    Dernier message: 12/03/2007, 16h51
  4. Probleme avec std::map
    Par olive_le_malin dans le forum SL & STL
    Réponses: 14
    Dernier message: 27/02/2007, 09h58
  5. Problem avec std::vector
    Par boiteweb dans le forum SL & STL
    Réponses: 5
    Dernier message: 29/04/2006, 12h56

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