Using Pair as Key in a Map (C++/Stl)

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

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.

Using pair<int, int> as key for map

you need a pair as a key cout << mymap[make_pair(1,2)] << endl; What you currently have cout << mymap[(1,2)] << endl; is not the correct syntax.

C++ STL map , std::pair as the key

Let's try:

typedef std::pair<std::string, std::string> my_key_type;
typedef std::map<my_key_type, int> my_map_type;

my_map_type m;

m.insert(my_map_type::value_type(my_key_type("A", "B"), 43));

Observe that the map's value_type is always std::pair<const key_type, mapped_type>, so in your case it's std::pair<my_key_type, int> -- a pair whose first member is itself a pair!

With that in mind you can alternatively use make_pair:

m.insert(std::make_pair(my_key_type("C", "D"), -5));

Finally, as Sven points out, there may or may not be a comparison operator for pairs (I think there is, though); so if there isn't, you have to write one yourself. Lexicographic comparison on the two elements should do. Sophie awaits :-)

(Here's the lexicographic pair comparison; you don't need to write this, it's already there:)

template<typename S, typename T>
bool operator<(const std::pair<S, T> & a, const std::pair<S, T> & b)
{
return (a.first < b.first) || (a.first == b.first && a.second < b.second);
}

How to get pair from a map using key in C++

An iterator for a map "points to" a std::pair<const KEY, VALUE>.

For your map, the KEY is char and the VALUE is std::pair<int, int>

So in your code, instead of:

std::pair<int, int> location = robots.find(robot_name);

you need to:

std::pair<int, int> location = robots.find(robot_name)->second;

Also, you need to check and see if the call to find fails to find the key you want. In that case the iterator will be equal to robots.end, and you'll have to deal with that:

const auto it = robots.find(robot_name);
if (it != robots.end()) {
return it->second;
} else {
// Not found, do something else
}

Insert a pair key in map

There are so many possibilities for this. You may choose any of the below which suits you better.

  1. Using make_pair
 map<pair<int,int>, int> m;
m.insert(make_pair(make_pair(5,20), 0));

  1. Using curly braces
 map<pair<int,int>, int> m;
m.insert({{5,20}, 0});

  1. Declaring a C++ Pair first
 pair<int,int> p(5,20);
map<pair<int,int>, int> m;
m.insert(make_pair(p, 0));

How to use STL unsorted key-value as pair in map

If you don't want ordering, don't use ordered containers like map or set. You could achieve what you're looking for using a class and a vector. The sorted nature of std::map is what makes it efficient to lookup by key. If you want/need unsorted and more hash like behavior for lookups, look at Boost unordered containers. Note that this doesn't guarantee the order in is going to be the order out. I'm assuming you want to preserve the order of the types your putting in the container, the example below will do that.

#include <iostream>
#include <vector>

using namespace std;

class DataBehavior
{
public:
DataBehavior(const string &type,
const string &data,
const string &behavior)
:type(type), data(data), behavior(behavior)
{
}

const string &getType() const { return type; }
const string &getData() const { return data; }
const string &getBehavior() const { return behavior; }

private:
string type;
string data;
string behavior;
};

typedef vector<DataBehavior> Ctr;

int main (int argc, char *argv[])
{
Ctr ctr;
ctr.push_back(DataBehavior("int", "50", "behavior"));
ctr.push_back(DataBehavior("int", "80", "behavior"));
ctr.push_back(DataBehavior("string", "25", "behavior2"));

for (Ctr::const_iterator it = ctr.begin(); it != ctr.end(); ++it)
{
cout << "Type: " << it->getType() << " "
<< "Data: " << it->getData() << " "
<< "Behavior: " << it->getBehavior() << "\n";
}
return 1;
}

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

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.

STL <map> allows duplicate pairs?

The second insert with the same key is a no-op. It simply returns an iterator pointing to the existing element.

std::map::insert() has a return value, which you should check.

It is of type std::pair<iterator,bool>. The second element of the pair tells you whether the element has been inserted, or whether there was already an existing entry with the same key.

cout << namemap.insert(pair<string,char>("yogendra",'a')).second << endl;
cout << namemap.insert(pair<string,char>("yogendra",'b')).second << endl;


Related Topics



Leave a reply



Submit