Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using pair as key in a map (C++ / STL)

I want to use a pair from STL as a key of a map.

#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;  } 

But the compiler throw a bunch of unreadable information and I'm very new to C and C++.

How can I use a pair as a key in a map? And in general How can I use any kind of structure (objects, structs, etc) as a key in a map?

Thanks!

like image 905
ccarpenterg Avatar asked Jul 18 '10 20:07

ccarpenterg


People also ask

Can I use pair as key in map?

Do you mean cout << mymap[make_pair(1,2)] << endl; ? (1,2) is non-sensical, at least in this context. You must have an std::pair to be used as your key, and that means following what @andre just commented. Yes!

Can you use a pair as a key in C++?

Using default order So, C++ expects operator< to be defined for the type used for map's keys. Since the operator< is already defined for pairs, we can initialize a std::map with std::pair as the key.

Can I use pair as key Unordered_map?

Unordered Map does not contain a hash function for a pair like it has for int, string, etc, So if we want to hash a pair then we have to explicitly provide it with a hash function that can hash a pair. unordered_map can takes upto 5 arguments: Key : Type of key values.

How do you put a pair on a map?

int a=10,b=20; map < pair < int,int >, int > m; pair < int,int >numbers = make_pair(a,b); int sum=a+b; m[numbers]=sum; Our map will have its key as pairs of numbers. We can access the integer values of pair variable using dot(.) operator.


2 Answers

std::map::insert takes a single argument: the key-value pair, so you would need to use:

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

You should use std::string instead of C strings in your types. As it is now, you will likely not get the results you expect because looking up values in the map will be done by comparing pointers, not by comparing strings.

If you really want to use C strings (which, again, you shouldn't), then you need to use const char* instead of char* in your types.

And in general How can I use any kind of structure (objects, structs, etc) as a key in a map?

You need to overload operator< for the key type or use a custom comparator.

like image 118
James McNellis Avatar answered Sep 28 '22 07:09

James McNellis


Here's a working rewrite of the code in 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; } 
like image 26
Alec Jacobson Avatar answered Sep 28 '22 06:09

Alec Jacobson