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 std::find_if


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut Problème avec std::find_if
    J'essaie de compiler le code suivant sans succès (VC++6.0):
    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
    41
    42
    43
    44
    45
    46
    47
    struct UneClasse
    {
    	std::string s_name;
    	bool s_wildchar;
    	UneClasse():s_wildchar(false) {}
    	UneClasse(const std::string & name,bool wildchar):s_name(name),s_wildchar(wildchar) {}
    	UneClasse(const UneClasse & r):s_name(r.s_name),s_wildchar(r.s_wildchar) {}
    	UneClasse & operator=(const UneClasse & r)
    		{ s_name=r.s_name;s_wildchar=r.s_wildchar;return *this; }
    	bool IsMatching(const std::string & name)
    	{
    		if (s_wildchar)
    			return ::strnicmp(s_name.c_str(),name.c_str(),s_name.length())==0;
    		else
    			return ::stricmp(s_name.c_str(),name.c_str())==0;
    	}
    };
     
    struct UneClassePred
    {
    	std::string s_name;
    	UneClassePred(std::string name):s_name(name) {}
    	bool operator()(const UneClasse & r)
    	{
    		if (r.s_wildchar)
    			return ::strnicmp(s_name.c_str(),r.s_name.c_str(),r.s_name.length())==0;
    		else
    			return ::stricmp(s_name.c_str(),r.s_name.c_str())==0;
    	}
    };
     
     
    int main(int argc, char* argv[])
    {
    	std::vector<UneClasse> v;
    	v.push_back(UneClasse("premier",false));
    	v.push_back(UneClasse("t",true));
    	v.push_back(UneClasse("second",false));
    	v.push_back(UneClasse("i",true));
     
    	std::vector<UneClasse>::iterator it1=std::find_if(v.begin(),v.end(),UneClassePred(std::string("troisième")));
     
    	std::vector<UneClasse>::iterator it2=std::find_if(v.begin(),v.end(),
    		std::bind2nd(std::mem_fun_ref<UneClasse,std::string>(&UneClasse::IsMatching),std::string("indefini")) // <- erreur compil VC++6.0
    		);
    	return 0;
    }
    Si quelqu'un a une idée pour m'indiquer où je fais une erreur.
    Pour info, le premier appel à find_if() fonctionne très bien en passant par la classe intermédiaire UneClassePred. Mais justement j'aimerais éviter cela.
    Merci.

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Plusieurs problèmes:
    1/ std::mem_fun_ref<UneClasse,std::string>(&UneClasse::IsMatching): tu oublies le type de retour dans les paramètres template et le type argument n'est pas le bon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::mem_fun_ref<bool, UneClasse,const std::string &>(&UneClasse::IsMatching)
    2/ Mais, cela ne suffit pas. Pour bind2nd, le second paramètre ne doit pas déjà être une référence. Donc, il faut changer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool IsMatching(std::string name)
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	std::vector<UneClasse>::iterator it2=std::find_if(v.begin(),v.end(),
    		std::bind2nd(std::mem_fun_ref<bool, UneClasse,std::string>(&UneClasse::IsMatching),std::string("indefini"))
    		);

  3. #3
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Je retire la référence dans UneClasse::IsMatching.

    Par contre le paramètre suplémentaire dans mem_fun_ref est refusé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error C2977: 'mem_fun_ref' : too many template arguments
    De fait, dans le header #include <functional> mem_fun_ref n'a que deux paramètres template.
    Pour rappel je suis sous VC++6.0.

    EDIT: d'après ce site http://www.ddj.com/cpp/184401583?pgno=3 se serait une lacune de VC++6...

  4. #4
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Voilà, j'ai modifié le code du header <functional> en ajoutant ceci à la fin (oui, j'ose modifier les header de VC++6 désormais, ils souffrent de quelques petits bugs):
    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    template<class _Result,
    	class _Ty>
    	class const_mem_fun_ref_t
    		: public unary_function<_Ty, _Result>
    	{	// functor adapter (*left.*pfunc)(), const *pfunc
    public:
    	explicit const_mem_fun_ref_t(_Result (_Ty::*_Pm)() const)
    		: _Pmemfun(_Pm)
    		{	// construct from pointer
    		}
     
    	_Result operator()(const _Ty& _Left) const
    		{	// call function
    		return ((_Left.*_Pmemfun)());
    		}
     
    private:
    	_Result (_Ty::*_Pmemfun)() const;	// the member function pointer
    	};
     
    		// TEMPLATE CLASS const_mem_fun1_ref_t
    template<class _Result,
    	class _Ty,
    	class _Arg>
    	class const_mem_fun1_ref_t
    		: public binary_function<_Ty, _Arg, _Result>
    	{	// functor adapter (*left.*pfunc)(val), const *pfunc
    public:
    	explicit const_mem_fun1_ref_t(_Result (_Ty::*_Pm)(_Arg) const)
    		: _Pmemfun(_Pm)
    		{	// construct from pointer
    		}
     
    	_Result operator()(const _Ty& _Left, _Arg _Right) const
    		{	// call function with operand
    		return ((_Left.*_Pmemfun)(_Right));
    		}
     
    private:
    	_Result (_Ty::*_Pmemfun)(_Arg) const;	// the member function pointer
    	};
     
    template<class _Result,
    	class _Ty> inline
    	const_mem_fun_ref_t<_Result, _Ty>
    		mem_fun_ref(_Result (_Ty::*_Pm)() const)
    	{	// return a const_mem_fun_ref_t functor adapter
    	return (std::const_mem_fun_ref_t<_Result, _Ty>(_Pm));
    	}
     
    template<class _Result,
    	class _Ty,
    	class _Arg> inline
    	const_mem_fun1_ref_t<_Result, _Ty, _Arg>
    		mem_fun_ref(_Result (_Ty::*_Pm)(_Arg) const)
    	{	// return a const_mem_fun1_ref_t functor adapter
    	return (std::const_mem_fun1_ref_t<_Result, _Ty, _Arg>(_Pm));
    	}
    Et mon code est à modifier simplement comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	std::vector<UneClasse>::iterator it2=std::find_if(v.begin(),v.end(),
    		std::bind2nd(std::mem_fun_ref(&UneClasse::IsMatching),std::string("indefini"))
    		);
    La méthode IsMatching() doit aussi être modifiée comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	bool IsMatching(std::string name) const
    Ça compile et ça s'exécute désormais comme il se doit.

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

Discussions similaires

  1. Problème avec std::string
    Par Laughing Man dans le forum C++
    Réponses: 18
    Dernier message: 07/02/2008, 19h04
  2. Problème avec std::multiplies
    Par Bakura dans le forum SL & STL
    Réponses: 8
    Dernier message: 25/05/2007, 19h07
  3. problème avec std::cin
    Par _LVEB_ dans le forum SL & STL
    Réponses: 4
    Dernier message: 20/02/2007, 00h35
  4. Problème avec std::vector
    Par dhoorens dans le forum SL & STL
    Réponses: 4
    Dernier message: 31/12/2006, 14h27
  5. Problème avec std::Vector
    Par mister3957 dans le forum SL & STL
    Réponses: 8
    Dernier message: 16/02/2006, 10h18

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