map with pair as key

Discussion in 'C++' started by kietzi@web.de, Jun 20, 2006.

  1. Guest

    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
     
    , Jun 20, 2006
    #1
    1. Advertising

  2. Mark P Guest

    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::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
     
    Mark P, Jun 20, 2006
    #2
    1. Advertising

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

    > 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
     
    Thomas J. Gritzan, Jun 20, 2006
    #3
  4. 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::pair<int,int>* pp1, std::pair<int,int>* pp2) const
    {
    return *pp1 < *pp2; // return std::less(*pp1, *pp2);
    }
    };

    Thomas
     
    Thomas J. Gritzan, Jun 20, 2006
    #4
  5. Guest

    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..
     
    , Jun 20, 2006
    #5
  6. wrote:
    > 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.
     
    Markus Schoder, Jun 20, 2006
    #6
  7. Guest

    > 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::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<().

    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>&)'
     
    , Jun 20, 2006
    #7
  8. Peter Guest

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


    std::map<std::pair<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
     
    Peter, Jun 20, 2006
    #8
  9. Mark P Guest

    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::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.
     
    Mark P, Jun 20, 2006
    #9
  10. 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::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<().

    > 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
     
    Thomas J. Gritzan, Jun 20, 2006
    #10
  11. Rolf Magnus Guest

    wrote:


    > 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>.
     
    Rolf Magnus, Jun 21, 2006
    #11
  12. silversurfer Guest

    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 Magnus schrieb:

    > wrote:
    >
    >
    > > 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>.
     
    silversurfer, Jun 21, 2006
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Patrick Guio
    Replies:
    6
    Views:
    3,210
    chris
    Oct 20, 2004
  2. Replies:
    2
    Views:
    556
    klaus hoffmann
    Feb 22, 2006
  3. Ian Collins

    map with pair of key

    Ian Collins, May 10, 2006, in forum: C++
    Replies:
    4
    Views:
    496
  4. Replies:
    1
    Views:
    569
    Daniel Pitts
    Nov 16, 2007
  5. Rui Maciel
    Replies:
    2
    Views:
    3,069
    AndrewDover
    Dec 1, 2009
Loading...

Share This Page