map with pair as key

K

kietzi

Hello world,
I was wondering whether it would be possible to create a map which uses
a pair of ints as key and a float as value. I have used maps with const
char*[] as key, but have so far not been successful to use a version
which uses pairs as keys.

For instance, I would like to set up the map as follows:

struct eqstr {
bool operator()(pair<int,int> s1, pair<int,int> s2) const{
return ((s1.first==s2.first) && (s1.second==s2.second));
}
};

std::map<std::pair<int,int>*, float, hash<const char*>, eqstr>
connections;

Unforunately, this does not work. How would I put elements into the map
and how could I access them? Where could be the problem with the eqstr
struct and map-initialization?

Thanks a lot you guys...

Tim
 
M

Mark P

Hello world,
I was wondering whether it would be possible to create a map which uses
a pair of ints as key and a float as value. I have used maps with const
char*[] as key, but have so far not been successful to use a version
which uses pairs as keys.

For instance, I would like to set up the map as follows:

struct eqstr {
bool operator()(pair<int,int> s1, pair<int,int> s2) const{
return ((s1.first==s2.first) && (s1.second==s2.second));
}
};

std::map<std::pair<int,int>*, float, hash<const char*>, eqstr>
connections;

First of all, hash is not standard C++.

More to the point, your map template parameters look to be out of whack.
The template parameters should be map<Key,Type,Compare,Alloc>. I'm
not sure how hash is supposed to fit into this scheme but what you need
is a less than function for the Key type. And clearly eqstr is not an
allocator-- most likely you don't need to specify this fourth parameter
at all.

For example...

struct PairCompare // or, ComPair :)
{
bool operator () (pair<int,int>* pp1, pair<int,int>* pp2) const
{
return pp1->first < pp2->first ||
pp1->first == pp2->first && pp1->second < pp2->second;
}
};

-Mark
 
T

Thomas J. Gritzan

Hello world,
I was wondering whether it would be possible to create a map which uses
a pair of ints as key and a float as value. I have used maps with const
char*[] as key, but have so far not been successful to use a version
which uses pairs as keys.

It is possible, I use something like this:
For instance, I would like to set up the map as follows:

struct eqstr {
bool operator()(pair<int,int> s1, pair<int,int> s2) const{
return ((s1.first==s2.first) && (s1.second==s2.second));
}
};

Your compare function should be true, when s1 is less than s2, not when
std::map<std::pair<int,int>*, float, hash<const char*>, eqstr>
connections;

1. Why do you have a pointer to pair as key? A value would do it.
Otherwise your functor would be called with pointers.
2. The compare functor should be the 3rd template parameter.
3. What is hash<> and why do you use it here?
4. "Unforunately, this does not work." does not help us. Copy&Paste the
error messages. Say, *what* went wrong, not *that* something went wrong.

Thomas
 
T

Thomas J. Gritzan

Mark said:
For example...

struct PairCompare // or, ComPair :)
{
bool operator () (pair<int,int>* pp1, pair<int,int>* pp2) const
{
return pp1->first < pp2->first ||
pp1->first == pp2->first && pp1->second < pp2->second;
}
};

Or like this:

struct PairLess
{
bool operator() (std::pair<int,int>* pp1, std::pair<int,int>* pp2) const
{
return *pp1 < *pp2; // return std::less(*pp1, *pp2);
}
};

Thomas
 
K

kietzi

I am sorry, I tried so many things that I mixed up some code-parts...
That is why the hash-element is still in there. The overall goal was to
use a hash-map because I thought that it is more efficient (than the
tree-map in the standart implementation).

Did I understand it right that the following should work:

struct PairCompare
{
bool operator () (pair<int,int>* pp1, pair<int,int>* pp2) const
{
return pp1->first < pp2->first ||
pp1->first == pp2->first && pp1->second < pp2->second;
}

};

std::map<std::pair<std::pair<int,int>,int>, some_value_type> ?

Now, I have a question to the latter element: Why should this not work:
std::map<std::pair<int,int>, some_value_type, PairLess > ??


At last:
1. Why do you have a pointer to pair as key? A value would do it.
Otherwise your functor would be called with pointers.
--> This is as well a try-version error from me..Normally, I use
values!

2. The compare functor should be the 3rd template parameter.
--> see above.. thanks for the tip. I found my version in a tutorial
(using hash_map)..Could it be that the hash_map.h needs the
equal-operator as fourth parameter?

3. What is hash<> and why do you use it here?
--> I wanted to use hash_map instead of map. This is why it was still
here.

4. "Unforunately, this does not work." does not help us. Copy&Paste the

error messages. Say, *what* went wrong, not *that* something went
wrong.
--> I got the most different error-messages one could imagine. Since I
changed the code from char* to pair as keys, I ot about 100 compiling
errors...

Again, thanks a lot for your help.
If the map is instantiated, would I add elements by using
pair<int,int> p (3,2);
connections[p]=3.3;
??

Thanks a lot once more..
 
M

Markus Schoder

Now, I have a question to the latter element: Why should this not work:
std::map<std::pair<int,int>, some_value_type, PairLess > ??

You do not need the third parameter unless you want to do something special.
std::pair<int, int> by default has a perfectly good operator<().

Please quote some relevant context when you are replying on Usenet. People
might not be seeing the posts you are replying too.
 
K

kietzi

Please quote some relevant context when you are replying on Usenet. People
might not be seeing the posts you are replying too.
Sorry.. my fault! I promise to better myself ;)
You do not need the third parameter unless you want to do something special.
std::pair<int, int> by default has a perfectly good operator<().
thanks, then I'll use
std::map<std::pair<int,int>, some_value_type >
as declaration - I tried it out a minute ago and it works.. Thanks so
much!

Nevertheless, a questions remains:
1. how could I use all this in a hash-map? I am importing "hash_map.h"
(should be within a SGI extension) and I am thinking of sth. like

hash_map<pair<int,int>, float> connections;
std::pair<int,int> p (2,3);
connections[p]=2.3;

unfortunately, I get the following compiling error, which makes no
sense to me:
..../include/c++/4.0.0/ext/hashtable.h:596: error: no match for call to
'(const __gnu_cxx::hash<std::pair<int, int> >) (const std::pair<int,
int>&)'
 
P

Peter

Hello world,
I was wondering whether it would be possible to create a map which uses
a pair of ints as key and a float as value. I have used maps with const

a pair provides all the required operators so this is fine.
char*[] as key, but have so far not been successful to use a version


a map with char ** as the key?
char ** does not provide any operators thus your code would not
compile.

which uses pairs as keys.

For instance, I would like to set up the map as follows:

struct eqstr {
bool operator()(pair<int,int> s1, pair<int,int> s2) const{
return ((s1.first==s2.first) && (s1.second==s2.second));
}
};


this operator is provided by pair so you don't need to provide it.
std::map<std::pair<int,int>*, float, hash<const char*>, eqstr>
connections;


a map using a pointer to a pair as key?
This code does not compile.
What is the problem with:
 
M

Mark P

Thomas said:
Or like this:

struct PairLess
{
bool operator() (std::pair<int,int>* pp1, std::pair<int,int>* pp2) const
{
return *pp1 < *pp2; // return std::less(*pp1, *pp2);
}
};

Thomas

Ah, good point. I'd forgotten that this was the supplied operator< for
pair.
 
T

Thomas J. Gritzan

Sorry.. my fault! I promise to better myself ;)

thanks, then I'll use
std::map<std::pair<int,int>, some_value_type >
as declaration - I tried it out a minute ago and it works.. Thanks so
much!

Nevertheless, a questions remains:
1. how could I use all this in a hash-map? I am importing "hash_map.h"
(should be within a SGI extension) and I am thinking of sth. like

Then it's offtopic here.
hash_map<pair<int,int>, float> connections;
std::pair<int,int> p (2,3);
connections[p]=2.3;

You can write this to avoid a temporary:

connections[ std::make_pair(2,3) ] = 2.3;
unfortunately, I get the following compiling error, which makes no
sense to me:
.../include/c++/4.0.0/ext/hashtable.h:596: error: no match for call to
'(const __gnu_cxx::hash<std::pair<int, int> >) (const std::pair<int,
int>&)'

I guess you need to supply a hash function as 3rd template parameter.
Read the SGI dokumentation and google for it.
Or simply use std::map for this. You souldn't think about efficiency of
the implementation until you need to.

If the interface of map and hash_map are equal, you should use typedef,
so you can simply switch from map to hash_map if you measured, that
hash_map is faster in your use case (it depends on your hash function, too).

Thomas
 
R

Rolf Magnus

Nevertheless, a questions remains:
1. how could I use all this in a hash-map? I am importing "hash_map.h"
(should be within a SGI extension)

This is off-topic here. Look into the documentation.
and I am thinking of sth. like

hash_map<pair<int,int>, float> connections;
std::pair<int,int> p (2,3);
connections[p]=2.3;

unfortunately, I get the following compiling error, which makes no
sense to me:
.../include/c++/4.0.0/ext/hashtable.h:596: error: no match for call to
'(const __gnu_cxx::hash<std::pair<int, int> >) (const std::pair<int,
int>&)'

Just a guess, but this looks to me as if you have to provide a function that
generates a hash value from a pair<int, int>.
 
S

silversurfer

sorry for writing off-topic, I thought that opening a whole new thread
for the hash-map would have been bad because the underlying problem was
dscussed here as well..

Thanks a lot for your help, it works and I am happy ;)

Rolf said:
Nevertheless, a questions remains:
1. how could I use all this in a hash-map? I am importing "hash_map.h"
(should be within a SGI extension)

This is off-topic here. Look into the documentation.
and I am thinking of sth. like

hash_map<pair<int,int>, float> connections;
std::pair<int,int> p (2,3);
connections[p]=2.3;

unfortunately, I get the following compiling error, which makes no
sense to me:
.../include/c++/4.0.0/ext/hashtable.h:596: error: no match for call to
'(const __gnu_cxx::hash<std::pair<int, int> >) (const std::pair<int,
int>&)'

Just a guess, but this looks to me as if you have to provide a function that
generates a hash value from a pair<int, int>.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top