Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > map with pair as key

Reply
Thread Tools

map with pair as key

 
 
kietzi@web.de
Guest
Posts: n/a
 
      06-20-2006
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:air<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

 
Reply With Quote
 
 
 
 
Mark P
Guest
Posts: n/a
 
      06-20-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> 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:air<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
 
Reply With Quote
 
 
 
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      06-20-2006
(E-Mail Removed) schrieb:
> 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:
std::map<std:air<std:air<int,int>,int>, some_value_type>

> 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
equal. std:air<> overloads operator<, so there is no need for a custom
compare functor.

> std::map<std:air<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
 
Reply With Quote
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      06-20-2006
Mark P schrieb:
> 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:air<int,int>* pp1, std:air<int,int>* pp2) const
{
return *pp1 < *pp2; // return std::less(*pp1, *pp2);
}
};

Thomas
 
Reply With Quote
 
kietzi@web.de
Guest
Posts: n/a
 
      06-20-2006
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:air<std:air<int,int>,int>, some_value_type> ?

Now, I have a question to the latter element: Why should this not work:
std::map<std:air<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..

 
Reply With Quote
 
Markus Schoder
Guest
Posts: n/a
 
      06-20-2006
(E-Mail Removed) wrote:
> Now, I have a question to the latter element: Why should this not work:
> std::map<std:air<int,int>, some_value_type, PairLess > ??


You do not need the third parameter unless you want to do something special.
std:air<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.

 
Reply With Quote
 
kietzi@web.de
Guest
Posts: n/a
 
      06-20-2006
> 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

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

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

thanks, then I'll use
std::map<std:air<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:air<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:air<int, int> >) (const std:air<int,
int>&)'

 
Reply With Quote
 
Peter
Guest
Posts: n/a
 
      06-20-2006

(E-Mail Removed) wrote:
> 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:air<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:


std::map<std:air<int, int>, float>


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


 
Reply With Quote
 
Mark P
Guest
Posts: n/a
 
      06-20-2006
Thomas J. Gritzan wrote:
> Mark P schrieb:
>> 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:air<int,int>* pp1, std:air<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.
 
Reply With Quote
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      06-20-2006
(E-Mail Removed) schrieb:
>> 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
>
>>> Now, I have a question to the latter element: Why should this not work:
>>> std::map<std:air<int,int>, some_value_type, PairLess > ??

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

> thanks, then I'll use
> std::map<std:air<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:air<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:air<int, int> >) (const std:air<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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
stl map: get the <key,value> pair which has the minimum value Rui Maciel C++ 2 12-01-2009 11:21 PM
map with pair of key Ian Collins C++ 4 05-10-2006 12:20 PM
a stl map which use stl pair as the key Allerdyce.John@gmail.com C++ 2 02-22-2006 07:25 AM
map.insert(key,val) vs. map[key]=val ? Patrick Guio C++ 6 10-20-2004 01:54 PM



Advertisments