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 :

impossible d'utiliser une clé de type complex dans un map !


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Par défaut impossible d'utiliser une clé de type complex dans un map !
    Boujours,

    Après avoir passé beaucoup de temps à chercher la solution, j'en appel à vôtre aide :

    Je ne comprend pas pourquoi la compilation plante lorsque je veux utiliser une clé de type complex dans un map!

    Voici un bout de code reproduisant le 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
    #include <string>
    #include <map>
    #include <list>
    #include <complex>
    #include <iostream>
     
    using namespace std;
     
    int main ( int argc, char *argv[] ) {
     
    	typedef string		 action;
    	typedef complex<int> state;	//PROBLEME avec le type complex !!!!
    	//typedef string state;	//Compilation OK en remplaçant complex<int> par string
    	//typedef int state;	//Compilation OK en remplaçant complex<int> par int
     
    	map< state, action > monMap;
    	action mouvement = "azerty";
    	state etat = complex<int>(-1,-1);	//PROBLEME avec le type complex !!!!
    	//state etat = "coucou";//Compilation OK en remplaçant complex<int> par string
    	//state etat = 2;	//Compilation OK en remplaçant complex<int> par int
     
    	monMap[etat] = mouvement;
    }
    Ce code ne compile pas si le typedef state est du type complex alors qu'il compile sans problèmes avec d'autre types ( j'ai essayé en mettant string ou int ) ( Le compilateur utilisé est VS2008 )

    Voici ce que me raconte le compilateur :

    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    ------ Build started: Project: Fourre_Tout_Console, Configuration: Debug Win32 ------
    Compiling...
    Fourre_Tout_Console.cpp
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::list<_Ty,_Ax> &,const std::list<_Ty,_Ax> &)' : could not deduce template argument for 'const std::list<_Ty,_Ax> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\list(1310) : see declaration of 'std::operator <'
            d:\program files\microsoft visual studio 9.0\vc\include\functional(142) : while compiling class template member function 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const'
            with
            [
                _Ty=state
            ]
            d:\program files\microsoft visual studio 9.0\vc\include\map(68) : see reference to class template instantiation 'std::less<_Ty>' being compiled
            with
            [
                _Ty=state
            ]
            d:\program files\microsoft visual studio 9.0\vc\include\xtree(22) : see reference to class template instantiation 'std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,_Mfl>' being compiled
            with
            [
                _Kty=state,
                _Ty=action,
                _Pr=std::less<state>,
                _Alloc=std::allocator<std::pair<const state,action>>,
                _Mfl=false
            ]
            d:\program files\microsoft visual studio 9.0\vc\include\xtree(63) : see reference to class template instantiation 'std::_Tree_nod<_Traits>' being compiled
            with
            [
                _Traits=std::_Tmap_traits<state,action,std::less<state>,std::allocator<std::pair<const state,action>>,false>
            ]
            d:\program files\microsoft visual studio 9.0\vc\include\xtree(89) : see reference to class template instantiation 'std::_Tree_ptr<_Traits>' being compiled
            with
            [
                _Traits=std::_Tmap_traits<state,action,std::less<state>,std::allocator<std::pair<const state,action>>,false>
            ]
            d:\program files\microsoft visual studio 9.0\vc\include\xtree(107) : see reference to class template instantiation 'std::_Tree_val<_Traits>' being compiled
            with
            [
                _Traits=std::_Tmap_traits<state,action,std::less<state>,std::allocator<std::pair<const state,action>>,false>
            ]
            d:\program files\microsoft visual studio 9.0\vc\include\map(78) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled
            with
            [
                _Traits=std::_Tmap_traits<state,action,std::less<state>,std::allocator<std::pair<const state,action>>,false>
            ]
            d:\visual studio 2010\projects\fourre_tout_console\fourre_tout_console\fourre_tout_console.cpp(16) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled
            with
            [
                _Kty=state,
                _Ty=action
            ]
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::list<_Ty,_Ax> &,const std::list<_Ty,_Ax> &)' : could not deduce template argument for 'const std::list<_Ty,_Ax> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\list(1310) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::list<_Ty,_Ax> &,const std::list<_Ty,_Ax> &)' : could not deduce template argument for 'const std::list<_Ty,_Ax> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\list(1310) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\xtree(1466) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\xtree(1466) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\xtree(1466) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\string(150) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\string(150) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\string(150) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\string(140) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\string(130) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\string(130) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\string(130) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\xutility(2236) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\xutility(2236) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\xutility(2236) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\xutility(2046) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\xutility(2046) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\xutility(2046) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\utility(84) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\utility(84) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const state'
            d:\program files\microsoft visual studio 9.0\vc\include\utility(84) : see declaration of 'std::operator <'
    d:\program files\microsoft visual studio 9.0\vc\include\functional(143) : error C2676: binary '<' : 'const state' does not define this operator or a conversion to a type acceptable to the predefined operator
    Build log was saved at "file://d:\visual studio 2010\Projects\Fourre_Tout_Console\Fourre_Tout_Console\Debug\BuildLog.htm"
    Fourre_Tout_Console - 23 error(s), 0 warning(s)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

  2. #2
    Membre éprouvé Avatar de Xtrem_Voyageur
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2009
    Messages : 85
    Par défaut
    Une map maintient un ordre, et pour cela utilise l'opérateur < pour comparer les clés.
    Pour des clés de type int, string, il n'y a pas de problèmes.
    Mais comparer 2 complexes, ...

  3. #3
    Membre chevronné

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Par défaut
    Ca a l'air pas bête ce que tu dis , je vais chercher comment changer la relation d'ordre de mon map pour en imposer une "faite maison"... Il me semble que c'est possible, je crois l'avoir déjà fait une fois... ( si quelqu'un à une piste, je n'arrive pas à retrouver la procédure pour faire ça : je vais fouiller dans la doc de référence... )

    Merci.

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    tu peux toujours ajouter un opérateur de comparaison fonctionnant sur les complexes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    bool operator < (std::complex const& c1, std::complexconst& c2) {
       return (c1.real() < c2.real()) || ((c1.real() == c2.real()) && (c1.imag() < c2;imag()));
    }
    Mais ça n'a pas de sens au niveau mathématique !

  5. #5
    Membre chevronné

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Par défaut
    Aucun souci si ça n'as pas de sens au niveau mathématique Guillaume, je veux seulement pouvoir créer un map avec un complex comme clé... C'est parfait.

    Je me suis inspiré de ce qu' proposé Guillaume dans le post ci-dessus et de ce que j'ai trouvé dans la doc de référence ( constructeur de map sur cplusplus.com )...

    Ca donne ça et ça compile pile poil !!!
    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
    #include <string>
    #include <map>
    #include <list>
    #include <complex>
    #include <iostream>
     
    using namespace std;
     
    bool fncomp (complex<int> c1, complex<int> c2) {
    	return (c1.real()<c2.real()) || ( (c1.real()==c2.real()) && (c1.imag()<c2.imag()));
    }
     
    bool(*fn_pt)(complex<int>,complex<int>) = fncomp;
     
    int main ( int argc, char *argv[] ) {
     
    	typedef string	action;
    	typedef complex<int> state;
     
    	map< state, action, bool(*)(complex<int>,complex<int>) > monMap (fn_pt);
    	action mouvement = "azerty";
    	state etat = complex<int>(-1,-1);
     
    	monMap[etat] = mouvement;
    }
    Merci à Xtrem_Voyageur et à Guillaume

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Ca marche, mais ce n'est assurément pas optimal. En effet, tu utilises un pointeur de fonction là où un foncteur te permettrait de bénéficier de l'inlining...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class ComplexComparer
    {
      bool operator()(complex<int> c1, complex<int> c2) 
      {
    	return (c1.real()<c2.real()) || ( (c1.real()==c2.real()) && (c1.imag()<c2.imag()));
      }
    };
     
    int main()
    {
        map< state, action, ComplexComparer> monMap;
    }
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Par défaut
    peut être qu'une unordered_map serait ici plus adaptée?

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

Discussions similaires

  1. [ASE] Impossible de supprimer une table de type tempdb..matable
    Par Malau dans le forum Adaptive Server Enterprise
    Réponses: 4
    Dernier message: 21/11/2007, 11h13
  2. [Free Pascal] [2.2] Impossible d'assigner une variable de type T à une variable de type T
    Par Hibou57 dans le forum Free Pascal
    Réponses: 3
    Dernier message: 12/10/2007, 12h31
  3. [XSLT] Comment utiliser une structure de type if-then-ELSE ?
    Par ribrok dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 27/11/2006, 12h39
  4. DAO impossible d'utiliser une fonction dans un requete
    Par exter666 dans le forum VBA Access
    Réponses: 10
    Dernier message: 24/09/2005, 17h15
  5. Impossible d'utiliser DISTINCT avec des types image et ntext
    Par azlinch dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 17/08/2005, 17h43

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