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 :

template derivé de la classe map


Sujet :

Langage C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2010
    Messages : 5
    Par défaut template derivé de la classe map
    bonjour,

    voici plusieurs jours que je lute pour trouver une solution a mon problème. Je souhaiterai créer une classe map personnalisé qui ajouterait une fonction permettant de trouver une clef par la valeur (donc la fonction inverse de find).
    J'aimerais utiliser cette technique parce que d'une part je trouve que c'est plus propre que d'utilisé 2 map complémentaires et d'autre part d'un point de vue éducatif je souhaiterais comprendre pourquoi mon 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
    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
    59
    60
     
    #ifndef _MAPINTOWWAYS_H
    #define	_MAPINTOWWAYS_H
     
    #include <map>
    #include <iostream>
    #include <algorithm>
     
     
    using namespace std;
     
    /*
    * fonction objet permetant de comparer une valeur avec celui d'un élement d'une map
    */
    template <class K, class V>
    class value_equals {
      private:
        V value;
      public:
        // constructeur (initialise la valeur à comparer)
        value_equals (const V& v)
         : value(v) {
        }
        // comparaison
        bool operator() (pair<const K, V> elem) {
            return elem.second == value;
        }
    };
     
    /*
    * classe template dérivant de la classe template map
    */
    template <typename _Key, typename _Tp, typename _Compare = less<_Key>,
                typename _Alloc = allocator<pair<const _Key, _Tp> > >
    class mapinTowWays : public map <_Key, _Tp, _Compare, _Alloc >
    {
     
    public:
     
        mapinTowWays(){}
        mapinTowWays(const mapinTowWays& orig){}
        virtual ~mapinTowWays(){}
     
        //ma fonction permettant de récupérer la clef en fonction de la valeur (si la valeur est unique)
        _Alloc findByValue(_Tp value ){
        	return find_if(this->begin(),this->end(),value_equals<_Key,_Tp>(value));
        }
     
        //idem avec un 2eme essai qui ne marche pas
        //ma fonction permettant de récupérer la clef en fonction de la valeur (si la valeur est unique)
    /*
        map<_Key,_Tp>::iterator findByValueV2(_Tp value ){
        	map<_Key,_Tp>::iterator iter;
        	iter=find_if(this->begin(),this->end(),value_equals<_Key,_Tp>(value));
            	return iter;
            }
    */
    };
     
    #endif	/* _MAPINTOWWAYS_H */
    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
     
    #include "mapinTwoWays.h"
    #include <map>
    #include <string>
    using namespace std;
     
    int main(int argc, char** argv) {
     
        //ca ca marche
        map<string,int> mymap;
        mymap["azerty"]=2;
        map<string,int>::iterator iter = find_if(mymap.begin(),mymap.end(),value_equals <string,int>(2));
        cout << "key: " << iter->first << "\tvalue: " << iter->second <<endl;
     
        //ca ca compile pas
        mapinTwoWays<string,int> mysupermap;
        mysupermap=["azerty"]=2
        mapinTwoWays<string,int>::iterator iter = mysupermap.findByValue(2);
        cout << "key: " << iter->first << "\tvalue: " << iter->second <<endl;
     
        return (EXIT_SUCCESS);
    }
    voila, je poste également les erreurs de compile:
    --> erreur avec la fonction commentée /*findByValueV2(_Tp value )*/

    **** Internal Builder is used for build ****
    g++ -O0 -g3 -Wall -c -fmessage-length=0 -omain.o ..\main.cpp
    ..\main.cpp: In function `int main(int, char**)':
    ..\main.cpp:16: error: `mapinTwoWays' was not declared in this scope
    ..\main.cpp:16: error: expected primary-expression before ',' token
    ..\main.cpp:16: error: expected primary-expression before "int"
    ..\main.cpp:16: error: expected `;' before "int"
    ..\main.cpp:17: error: `mysupermap' was not declared in this scope
    ..\main.cpp:17: error: expected primary-expression before '[' token
    ..\main.cpp:18: error: expected `;' before "mapinTwoWays"
    ..\main.cpp:16: warning: unused variable 'mapinTwoWays'
    ..\main.cpp:17: warning: unused variable 'mysupermap'
    C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h: In function `_InputIterator std::find_if(_InputIterator, _InputIterator, _Predicate, std::input_iterator_tag) [with _InputIterator = std::_Rb_tree_iterator<std::pair<const std::string, int> >, _Predicate = int]':
    C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:336: instantiated from `_InputIterator std::find_if(_InputIterator, _InputIterator, _Predicate) [with _InputIterator = std::_Rb_tree_iterator<std::pair<const std::string, int> >, _Predicate = int]'
    ..\main.cpp:12: instantiated from here
    C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:187: error: `__pred' cannot be used as a function
    Build error occurred, build is stopped
    Time consumed: 390 ms.

    voila. si quelqu'un a une idée, ca serai vraiment trés sympa de me la faire partager parce que moi j'en ai plus...

    (PS: j'ai bien regardé le FAQ sur les templates concernant l'héritage avant de poster mais je n'y ai pas trouvé ma réponse)

    cordialement

  2. #2
    Invité
    Invité(e)
    Par défaut
    Tu as fais un faute de frappe dan ton fichier "mapinTwoWays.h"(mapinTowWays) et pourquoi renvoyer un _Alloc?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Par défaut
    Tu peux éventuellement utiliser boost.bimap qui fait déjà ce que tu cherches à faire.

  4. #4
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    C'est pas une bonne idée de dérivé publiquement de map...

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2010
    Messages : 5
    Par défaut
    rebonjour,
    alors effectivement, j'ai gaffé quand j'ai extrais le code du projet sur lequel j'étais entrain de travailler. (d'ailleurs bien

    vue pour la faute de frape )

    Je reposte donc le code corrigé. et effectivement comme le souligné Joe Dralliam, je ne retournais pas le bon type. le

    map<_Key,_Tp>::iterator est en faite un _Rb_tree_iterator<pair<const _Key, _Tp> >

    en tous cas, merci à tous pour vos réponses.

    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
     
    #include "mapinTwoWays.h"
    #include <map>
    #include <string>
    using namespace std;
     
    int main(int argc, char** argv) {
     
        map<string,int> mymap;
        mymap["azerty"]=2;
        map<string,int>::iterator iter;
        iter = find_if(mymap.begin(),mymap.end(),value_equals <string,int>(2));
        cout << "key: " << iter->first << "\tvalue: " << iter->second <<endl;
     
        mapinTwoWays<string,int> mysupermap;
        mysupermap["azerty"]=2;
        mapinTwoWays<string,int>::iterator iter2 = mysupermap.findByValue(2);
        cout << "key: " << iter->first << "\tvalue: " << iter->second <<endl;
     
        return (EXIT_SUCCESS);
    }
    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
     
    #ifndef _MAPINTWOWAYS_H
    #define	_MAPINTWOWAYS_H
     
    #include <map>
    #include <iostream>
    #include <algorithm>
     
    using namespace std;
     
    /*
    * fonction objet permetant de comparer une valeur avec celui d'un élement d'une map
    */
    template <class K, class V>
    class value_equals {
      private:
        V value;
      public:
        // constructeur (initialise la valeur à comparer)
        value_equals (const V& v)
         : value(v) {
        }
        // comparaison
        bool operator() (pair<const K, V> elem) {
            return elem.second == value;
        }
    };
     
    /*
    * classe template dérivant de la classe template map
    */
    template <typename _Key, typename _Tp, typename _Compare = less<_Key>,
                typename _Alloc = allocator<pair<const _Key, _Tp> > >
    class mapinTwoWays : public map <_Key, _Tp, _Compare, _Alloc >
    {
     
    public:
        mapinTwoWays(){}
        virtual ~mapinTwoWays(){}
     
        //ma fonction permettant de récupérer la clef en fonction de la valeur (si la valeur est unique)
        _Rb_tree_iterator<pair<const _Key, _Tp> > findByValue(_Tp value ){
        	return find_if(this->begin(),this->end(),value_equals<_Key,_Tp>(value));
        }
    };
     
    #endif	/* _MAPINTWOWAYS_H */

  6. #6
    Invité
    Invité(e)
    Par défaut
    Si c'est pour t'entrainer que tu fais cette classe:
    -il ne faut jamais (ou presque) utiliser un using namespace dans un header.
    -_Rb_tree_iterator est l'implémentation de std::map::iterator de MinGW et donc n'est pas portable.
    -tu peux aussi utiliser std::bind1st et std::equal_to à la place de ton foncteur
    -et enfin pourquoi declarer le destructeur virtuel?

    Sinon cherche une classe déjà faites(par exemple celle de boost) qui sera sans doute mieux optimisée et offrira plus de possibilité.
    Dernière modification par Deepin ; 26/07/2011 à 09h07.

  7. #7
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Au risque de me répéter std::map, n'a pas pour but d'être dérivé publiquement.

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

Discussions similaires

  1. classe, map ou structure?
    Par falynne dans le forum C++
    Réponses: 17
    Dernier message: 27/12/2007, 14h24
  2. Réponses: 8
    Dernier message: 20/07/2007, 14h28
  3. [Template] Surchage d'une class template
    Par vincho dans le forum Langage
    Réponses: 3
    Dernier message: 15/05/2007, 11h29
  4. classe map et affectation
    Par alexadvance dans le forum C++
    Réponses: 11
    Dernier message: 07/03/2007, 15h31
  5. Template d'une fonction (!= classe)
    Par Rodrigue dans le forum Langage
    Réponses: 7
    Dernier message: 08/05/2006, 22h02

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