ccarpenterg
ccarpenterg

Reputation: 799

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!

Upvotes: 46

Views: 91335

Answers (6)

Shishir Jaiswal
Shishir Jaiswal

Reputation: 135

std::map::emplace is your friend.

mapa.emplace(p1, "Manzana");

Upvotes: 0

Kumar Utkarsh
Kumar Utkarsh

Reputation: 11

This is a similar version of what you want to do, just change the data types, that's all. Also, use a c++ string, not the one we use in c.

#include<bits/stdc++.h>
using namespace std;
#define  ll long long int
typedef pair<ll,ll> my_key_type;
typedef map<my_key_type,ll> my_map_type;
int  main()
{
    my_map_type m;
    m.insert(make_pair(my_key_type(30,40),6));
}   

Upvotes: 1

trahul
trahul

Reputation: 21

This is will do exactly what you want

#include<bits/stdc++.h>
using namespace std;
int main()
{
    map<pair<string, long long int>, string> MAP;
    pair<string, long long int> P;
    MAP.insert(pair<pair<string, long long int>, string>(pair<string, long long int>("Apple", 45), "Manzana"));
    MAP.insert(pair<pair<string, long long int>, string>(pair<string, long long int>("Berry", 20), "Arandano"));
    P = make_pair("Berry", 20);
    //to find berry, 20
    cout<<MAP[P]<<"\n";
    return 0;
}

Upvotes: -1

Julian Declercq
Julian Declercq

Reputation: 1596

Alternatively to what James McNellis stated:

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

you could use mapa.insert({p1, "Manzana"});

Upvotes: 5

Alec Jacobson
Alec Jacobson

Reputation: 6274

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

Upvotes: 8

James McNellis
James McNellis

Reputation: 355347

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.

Upvotes: 36

Related Questions