web-dev-qa-db-fra.com

Utiliser une paire comme clé dans une carte (C++/STL)

Je veux utiliser une paire de STL comme clé d'une carte.

#include <iostream>
#include <map>

using namespace std;

int main() {

typedef pair<char*, int> Key;
typedef map< Key , char*> Mapa;

Key p1 ("Apple", 45);
Key p2 ("Berry", 20);

Mapa mapa;

mapa.insert(p1, "Manzana");
mapa.insert(p2, "Arandano");

return 0;

}

Mais le compilateur jette un tas d'informations illisibles et je suis très novice en C et C++.

Comment utiliser une paire comme clé dans une carte? Et en général, comment puis-je utiliser n'importe quel type de structure (objets, structures, etc.) comme clé dans une carte?

Merci!

29
ccarpenterg

std::map::insert prend un seul argument: la paire clé-valeur. Vous devez donc utiliser:

mapa.insert(std::make_pair(p1, "Manzana"));

Vous devriez utiliser std::string au lieu de chaînes C dans vos types. Dans l'état actuel des choses, vous n'obtiendrez probablement pas les résultats escomptés, car la recherche des valeurs sur la carte se fera en comparant les pointeurs et non en comparant les chaînes.

Si vous voulez vraiment utiliser les chaînes de caractères C (ce qui, encore une fois, vous ne devriez pas le faire), vous devez alors utiliser const char* au lieu de char* dans vos types.

Et en général, comment puis-je utiliser n'importe quel type de structure (objets, structures, etc.) comme clé dans une carte?

Vous devez surcharger operator< pour le type de clé ou utiliser un comparateur personnalisé.

28
James McNellis

Voici une réécriture du code en question:

#include <map>
#include <string>

class Key
{
  public: 
    Key(std::string s, int i)
    {
      this->s = s;
      this->i = i;
    }
    std::string s;
    int i;
    bool operator<(const Key& k) const
    {
      int s_cmp = this->s.compare(k.s);
      if(s_cmp == 0)
      {
        return this->i < k.i;
      }
      return s_cmp < 0;
    }
};

int main()
{


  Key p1 ("Apple", 45);
  Key p2 ("Berry", 20);

  std::map<Key,std::string> mapa;

  mapa[p1] = "Manzana";
  mapa[p2] = "Arandano";

  printf("mapa[%s,%d] --> %s\n",
    p1.s.c_str(),p1.i,mapa.begin()->second.c_str());
  printf("mapa[%s,%d] --> %s\n",
    p2.s.c_str(),p2.i,(++mapa.begin())->second.c_str());

  return 0;
}
6
Alec Jacobson

Alternativement à ce que James McNellis a déclaré: 

mapa.insert(std::make_pair(p1, "Manzana"));

vous pouvez utiliser mapa.insert({p1, "Manzana"});

4
Julian Declercq