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 :

Problème avec la fonction find_if


Sujet :

SL & STL C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut Problème avec la fonction find_if
    Bonjour,
    j'aimerais utiliser la fonction find_if sans prédicat "maison", et donc en l'utilisant avec une fonction membre existante.
    J'ai donc fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	std::vector<COperateur*>::const_iterator iter = std::find_if( m_listOp.begin(), m_listOp.end(), std::bind2nd( std::mem_fun(&COperateur::IsAddIp), addIp) );
     
    avec :
    	bool IsAddIp(const std::string& addIp) const {
            return (bool)(GetAddIp() == addIp);
    	}

    Erreur :
    error C2784: 'class std::mem_fun_t<_R,_Ty> __cdecl std::mem_fun(_R (__thiscall _Ty::*)(void))' : could not deduce template argument for '<Unknown>' from 'bool (__thiscall COperateur::*)(const class std::basi
    c_string<char,struct std::char_traits<char>,class std::allocator<char> > &) const'
    Selon vous d'où vient le problème ?
    - encore VC6 ?
    - devrais-je utiliser std::mem_fun1 du fait que ma fonction membre prend un argument ?

    Merci par avance,
    @+

  2. #2
    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
    - devrais-je utiliser std::mem_fun1 du fait que ma fonction membre prend un argument ?
    Normalement la fonction std::mem_fun est suffisamment bien surchargée pour utiliser toute seule la structure appropriée.

    - encore VC6 ?
    Ca m'étonnerait pas. Je crois me souvenir que ce genre d'appels est un peu trop compliqué pour VC6, mais enfin c'est à vérifier. En tout cas je ne vois a priori pas d'erreur flagrante.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut
    OK, j'essaierai sous VS2005 ...
    Sinon, quelle est la différence avec mem_fun1 ? j'arrive pas trop à voir ...

  4. #4
    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
    mem_fun1 c'est pour les fonctions prenant un paramètre, mais j'avais remarqué que mem_fun avait des surcharges pour gérer ces cas-là aussi. Après ce n'est qu'une constatation, ce n'est peut-être pas standard.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut
    salut,
    ha ben celle là elle est bonne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    	std::vector<COperateur*>::const_iterator iter = std::find_if( m_listOp.begin(), m_listOp.end(), std::bind2nd( std::mem_fun1(&COperateur::IsTest), 0 ) );
     
    avec:
    	bool COperateur::IsTest(int a) {
            return true;
    	}
    ça marche ...

    mais si je remplace int <--> std::string en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    	bool IsTest(const std::string& a) {
            return true;
    	}
    je reviens à mes erreurs !



    Donc il semble qu'il ne faut pas que la fonction membre prenne en paramètre une référence constante ...

  6. #6
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    mem_fun1 n'est pas définie par le standard. En revanche, mem_fun est bien surchargée et doit créer un objet de type mem_fun1_t lorsqu'un paramètre est fourni à la fonction appelée.
    l'implémentation de la STL dans visual fourni cette fonction mem_fun1, qui fait la même chose que la fonction mem_fun surchargée. Je ne sais pas pourquoi il ont fait ça, mais ce n'est n'est pas standard.

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut
    OK pour mem_fun et mem_fun1, ce qui rejoint la réponse de Laurent.
    Par contre ce n'est pas exact sous VC6 : si on essaie d'utiliser mem_fun en lieu et place de mem_fun1 on se retrouve avec une erreur :
    error C2784: 'class std::mem_fun_t<_R,_Ty> __cdecl std::mem_fun(_R (__thiscall _Ty::*)(void))' : could not deduce template argument for '<Unknown>' from 'bool (__thiscall COperateur::*)(class std::basic_stri
    ng<char,struct std::char_traits<char>,class std::allocator<char> >)'
    Mais comment expliquer, en utilisant bien mem_fun1 pour que VC6 soit content, le problème des const références ?

  8. #8
    Membre émérite Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Par défaut
    Citation Envoyé par olive_le_malin Voir le message
    OK pour mem_fun et mem_fun1, ce qui rejoint la réponse de Laurent.
    Par contre ce n'est pas exact sous VC6 : si on essaie d'utiliser mem_fun en lieu et place de mem_fun1 on se retrouve avec une erreur :


    Mais comment expliquer, en utilisant bien mem_fun1 pour que VC6 soit content, le problème des const références ?
    Pour ça, il faut utiliser boost::bind, qui règle le problème. (après, il y a peut être des problèmes de VC6 qui restent...)

  9. #9
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Je ne parviens pas à cerner le problème.
    Ce qui est certain, c'est que le problème ne vient pas du const, mais du fait que le paramètre soit passé par référence.

    Ce code fonctionne chez moi (visual 2005):
    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 <algorithm>
    #include <vector>
    #include <functional>
     
    class COperateur
    {
    public:
    	COperateur(int a = 2):number(a){}
    	bool IsSup(const COperateur a ) const { return number>a.number; };
    	int number;
    };
     
    int main()
    {	
    	std::vector<COperateur*> m_listOp;
    	m_listOp.push_back(new COperateur(0));
    	m_listOp.push_back(new COperateur(1));
    	m_listOp.push_back(new COperateur(2));
     
    	std::vector<COperateur*>::const_iterator iter;
    	iter = std::find_if( m_listOp.begin(), 
    		m_listOp.end(), 
    		std::bind2nd( std::mem_fun(&COperateur::IsSup), COperateur(1) ) );
     
    	return 0;
    }
    (et j'utilise bien mem_fun (tout court) ).

    Mais pourquoi ça ne fonctionne pas si je passe une référence à IsSup, je l'ignore.

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut
    ha toi aussi alors tu as le pb avec les références ? et tu as une erreur de référence sur référence, non ?
    Bon ... ça ne vient pas que de moi et mon vieux compilo si ça le fait aussi sur les récents

  11. #11
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Oui, c'est un problème de référence sur référence. Même erreur avec gcc également.
    Si on remplace la référence par un pointeur, ça fonctionne, mais bon...

  12. #12
    Membre émérite Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Par défaut
    Oui avec les références ça ne marche pas, c'est une limitation de std::bind1st et std::bind2nd.

    En mettant ça, ça marche :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    boost::bind( &COperateur::IsSup, _1, COperateur(1) )
    au lieu de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::bind2nd( std::mem_fun(&COperateur::IsSup), COperateur(1) )

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut
    merci Hanlee pour cet éclairage.
    Je me pencherais alors un peu plus sur boost ...

    MErci à vous
    @+

  14. #14
    Membre émérite Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Par défaut
    Citation Envoyé par olive_le_malin Voir le message
    merci Hanlee pour cet éclairage.
    Je me pencherais alors un peu plus sur boost ...

    MErci à vous
    @+
    En tout cas, tu peux déjà savoir que boost::bind sera adopté dans le prochain standard de C++.

  15. #15
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut
    et oui je sais ....
    d'où le fait qu'il va vraiment falloir que regarde de façon + générale boost !
    @+

  16. #16
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575

  17. #17
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut
    Merci !

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

Discussions similaires

  1. Problème avec la fonction find_if
    Par olive_le_malin dans le forum C++
    Réponses: 3
    Dernier message: 22/08/2007, 14h29
  2. Retourner une valeur avec une fonction
    Par stephtbest dans le forum ASP
    Réponses: 4
    Dernier message: 31/10/2003, 16h37
  3. [Postgresql]Problème avec les fonctions ...
    Par fet dans le forum Requêtes
    Réponses: 4
    Dernier message: 02/10/2003, 09h04
  4. Réponses: 13
    Dernier message: 20/03/2003, 08h11
  5. [VBA-E] avec une fonction value
    Par laas dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 28/11/2002, 13h22

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