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 :

classe template et prédicat


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Par défaut classe template et prédicat
    Bonjour à tous ,
    Je pense que ce problème a déjà été soulevé quelque part sur ce forum mais je n'ai pas le temps de chercher trop longtemps. En fait, pour faire simple, je dispose d'une classe templatée et abstraite :
    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
     
    template <typename T, typename U>
    class Curve
    {
        public:
            [...]
     
            bool isntValueInInterval(const U &value) const
            {
                if((U)value>=m_xMin&&(U)value<=m_xMax)
                    return false;
                return true;
            }
     
        protected:
            U m_xMin, m_xMax;
            [...]
    };
    La fonction isntValueInInterval permet simplement de savoir si une valeur en X est comprise dans l'intervalle de définition de la fonction [xMin;xMax] de la classe.
    Dans une autre classe, héritant de la classe Curve, une instruction permet de placer les solutions d'équations diverses (rendues compte par différentes classe dérivant de la classe Curve) dans une liste.
    Ces solutions peuvent être non comprises dans l'intervalle de la Curve actuelle et je ne veux pas que cela se produise, c'est pourquoi je voudrais utiliser la méthode remove_if(...) sur la liste contenant les solutions, avec le prédicat isntValueInInterval de la classe Curve.
    D'où cette ligne de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    results.remove_if(Curve<T,U>::isntValueInInterval);
    Cependant, même si j'ai essayé de nombreux autres arguments à la place de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Curve<T,U>::isntValueInInterval
    (pointeurs ...), cela ne fonctionne pas : le compilateur me renvoie :
    "no matching function for call to [...]::remove_if(<unknow type>)"
    J'ai pensé remplacer la fonction "isntValueInInterval(const U &value)" par "isntValueInInterval(const U &value, U min, Umax)" afin de ne pas "dépendre" des attributs de la classe Curve et éventuellement placer cette fonction en statique, mais il y a trop d'arguments et bind3rd n'existe pas dans la STL (ou alors je suis aveugle ^^).
    Dois-je continuer sur cette piste (créer 2 fonctions à la place d'une seule : une fonction isBeforeMin et une fonction isAfterMax afin de n'avoir que 2 arguments et donc de pouvoir utiliser bind2nd 2 fois par la suite) ou partir sur autre chose ? Eventuellement une autre classe ?

    Merci par avance pour votre aide

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Bonjour,

    Quand tu as un problème de ce genre (un instruction qui ne compile pas) l'idéal est de réussir à produire un code minimal (disons moins de 50 lignes) qui reproduit l'erreur, ca permet :
    -> Aux personnes qui veulent t'aider d'identifier exactement ton problème
    -> Quelques fois à résoudre toi même ton problème.

    Parce que là avec les informations qu'on a on peut pas te dire d'où vient ton problème :
    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
     
    #include<algorithm>
    #include<functional>
    #include<list>
     
    template<class U>
    class Curve
    {
    protected:
    	U m_xMin, m_xMax;
     
    public:
    	bool isntValueInInterval(const U& value) const
    	{ return value<m_xMin || value>m_xMax; }
    };
     
    template<class U>
    class Sol : public Curve<U>
    {
    	std::list<U> list;
     
    public:
    	void find()
    	{
    		/*some stuff*/
    		std::remove_if(list.begin(),list.end()
    			,std::bind(&Curve<U>::isntValueInInterval,*this,std::placeholders::_1));
    	}
    };
    Compile.

    PS: Tu remarques au passage que ton prédicat se simplifie En général une conditionnel qui retourne true ou false, ca revient à tout simplement retourner l'évaluation de la condition

  3. #3
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Par défaut
    Merci pour ta réponse, cependant le compilateur m'indique qu'il ne reconnaît pas std::placeholder (has not been declared). Quel entête autre que functional faut-il inclure ?
    De plus, j'ai "installé" boost et maintenant cela génère un conflit entre std::bind et boost::bind : j'ai l'impression que std::bind n'est plus reconnu à cause de cela alors qu'il l'était auparavant.
    Dernier "détail", je m'aperçois que sur windows std::bind n'est pas reconnu, je précise que je viens de réinstaller ubuntu sur un autre ordinateur et que sur celui-ci la version du compilateur est sans doute plus récente (std::bind est (était avant l'installation de boost) reconnu sur l'ordi "linux").
    Ou alors j'ai oublié d'inclure certains entêtes importants ?

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Il faut compiler en mode C++11 (*) (j'ai testé sous VC++ et gcc sous windows).

    Il ne devrait pas y avoir de conflit, les namespaces sont là (sauf si tu as fait deux "using namespace" et utilisé un appel non qualifié) pour les lever. Il est possible qu'il y en reste, mais encore une fois un code minimal montrant ce conflit serait plus simple pour t'expliquer pourquoi il existe. (l'ADL (**) peut peut-être en produire dans certaines situations)

    (*) Ou utiliser uniquement boost qui propose des outils similaire (quasi-identique même).

    (**) Si les arguments sont de type issue à la fois du namespace std et boost, il se peut qu'il recherche la fonction dans les deux namespaces à la fois, dans ce cas il faut nécessairement qualifier l'appel (chose qui était faite dans mon code BTW).

  5. #5
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Par défaut
    Oui effectivement j'ai décidé d'utiliser boost car je ne crois pas disposer du C++11
    Sinon après quelques recherches et grâce à ton morceau de code je commence à comprendre le fonctionnement de la fonction boost::bind et j'ai trouvé une erreur qui n'avait rien à voir avec bind justement
    J'écrivais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    results.remove_if(results.begin(),results.end(),!boost::bind(&Curve<T,U>::isValueInInterval,this,_1));
    Au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    remove_if(results.begin(),results.end(),!boost::bind(&Curve<T,U>::isValueInInterval,this,_1));
    Ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    results.remove_if(!boost::bind(&Curve<T,U>::isValueInInterval,this,_1));
    EDIT : Les 2 lignes précédentes ne sont pas du tout équivalentes, en effet après quelques tests il s'avère que seule la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    results.remove_if(!boost::bind(&Curve<T,U>::isValueInInterval,this,_1));
    effectue la bonne opération en supprimant réellement les éléments de la liste, sinon l'autre ne fait que replacer les éléments de la liste en déplaçant ceux qui ne satisfont pas le prédicat à la fin.
    Avez-vous une explication ? Une histoire de pointeur/référence ?

    EDIT 2 : En fait après quelques recherches il semblerait que tout cela soit parfaitement normal et définisse le comportement de la fonction std::remove_if

Discussions similaires

  1. Problèmes de fonctions membres de classe templates, gcc3.3.6
    Par yves.dessertine dans le forum Autres éditeurs
    Réponses: 12
    Dernier message: 17/10/2005, 21h36
  2. Trouver le Type d'une classe template dynamiquement ?
    Par Serge Iovleff dans le forum Langage
    Réponses: 3
    Dernier message: 23/09/2005, 16h48
  3. [DLL/classe template] problème de link
    Par Bob.Killer dans le forum C++
    Réponses: 7
    Dernier message: 31/08/2005, 18h56
  4. Class template hérité
    Par Azharis dans le forum Langage
    Réponses: 4
    Dernier message: 24/06/2005, 22h03
  5. Réponses: 6
    Dernier message: 06/10/2004, 12h59

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