map with pair of key

Discussion in 'C++' started by Ian Collins, May 10, 2006.

  1. Ian Collins

    Ian Collins Guest

    Florent Garcin wrote:
    > Hello!
    >
    > I would like to use the map structure with a key of Pair<string, string>
    > and an int as the value.
    >

    Didn't this come up a few days ago?

    > Pair is defined as:
    >
    > template <class T1, class T2>
    > class Pair
    > {
    > public:
    > T1 first;
    > T2 second;
    >
    > Pair()
    > {
    > }
    >
    > Pair(T1 first, T2 second)
    > {
    > this->first = first;
    > this->second = second;

    Use initialiser lists.
    > }
    >
    > virtual ~Pair()
    > {
    > }
    >
    > bool operator == (const Pair<T1, T2> p) const


    Use const Pair&
    > {
    > return (first == p.first && second == p.second) || (first == p.second
    > && second == p.first);
    > }
    >
    > bool operator < (const Pair<T1, T2> p) const


    Use const Pair&
    > {
    > return !(*this == p) && (first < p.first || (!(p.first < first) &&
    > second < p.second));
    > }
    >
    > };
    >
    > That means the two pairs of, for instance, strings ("A", "B") and ("B",
    > "A") are equals.
    >

    Where are your tests for the above assertion? Add some and you should
    find your problem.

    --
    Ian Collins.
    Ian Collins, May 10, 2006
    #1
    1. Advertising

  2. "Florent Garcin" <> wrote in message
    news:...
    : I would like to use the map structure with a key of Pair<string, string>
    : and an int as the value.
    :
    : Pair is defined as:
    ....
    : bool operator < (const Pair<T1, T2> p) const
    : {
    : return !(*this == p) && (first < p.first || (!(p.first < first) &&
    : second < p.second));
    : }
    ....
    : That means the two pairs of, for instance, strings ("A", "B") and ("B",
    : "A") are equals.

    Well, this is not what your operator < implies: as it looks through
    map elements using a bunary search based on op<, the functions of std::map
    will be taken away from the entry being looked for.

    But does it make sense for your pair class to accept separate types for
    its two elements if the elements are supposed to be interchangeable ??
    I don't think so.

    : Unfortunately, when I run the following code, I have a strange
    behaviour.
    ....
    : Why is it not as expected? Does anyone know what I'm doing wrong?

    When std::map does not behave as expected, always check your ordering
    function.
    If you want the order of the pair's element no not matter,
    try something like:
    friend bool operator < ( .... a, .... b )
    {
    T const* a1 = &a.first;
    T const* a2 = &a.second;
    if( *a2<*a1 ) swap( a1, a2 );
    T const* b1 = &b.first;
    T const* b2 = &b.second;
    if( *b2<*b1 ) swap( b1, b2 );
    return (*a1<*b1)||(!(*b1<*a1)&&(*a2<*b2);
    }
    Or possibly better & easier: keep the two elements of your
    pair class ordered at all times ( e.g. swap first & second
    if the latter is smaller ).



    Amicalement --Ivan
    --
    http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
    Ivan Vecerina, May 10, 2006
    #2
    1. Advertising

  3. John schrieb:
    >
    >>> Pair is defined as:
    >>>
    >>> template <class T1, class T2>
    >>> class Pair
    >>> {
    >>> public:
    >>> T1 first;
    >>> T2 second;
    >>>
    >>> Pair()
    >>> {
    >>> }
    >>>
    >>> Pair(T1 first, T2 second)
    >>> {
    >>> this->first = first;
    >>> this->second = second;

    >> Use initialiser lists.

    >
    > what do you mean?
    >


    Pair(T1 first_, T2 second_)
    : first(first_), second(second_)
    {
    }


    /S
    --
    Stefan Naewe
    naewe.s_AT_atlas_DOT_de
    =?ISO-8859-1?Q?Stefan_N=E4we?=, May 10, 2006
    #3
  4. Hello!

    I would like to use the map structure with a key of Pair<string, string>
    and an int as the value.

    Pair is defined as:

    template <class T1, class T2>
    class Pair
    {
    public:
    T1 first;
    T2 second;

    Pair()
    {
    }

    Pair(T1 first, T2 second)
    {
    this->first = first;
    this->second = second;
    }

    virtual ~Pair()
    {
    }

    bool operator == (const Pair<T1, T2> p) const
    {
    return (first == p.first && second == p.second) || (first == p.second
    && second == p.first);
    }

    bool operator < (const Pair<T1, T2> p) const
    {
    return !(*this == p) && (first < p.first || (!(p.first < first) &&
    second < p.second));
    }

    };

    That means the two pairs of, for instance, strings ("A", "B") and ("B",
    "A") are equals.

    Unfortunately, when I run the following code, I have a strange behaviour.

    map<const Pair<string, string>, int> myMap;

    bonds[Pair<string, string>("A", "B")] = 1;
    bonds[Pair<string, string>("A", "C")] = 2;
    bonds[Pair<string, string>("A", "D")] = 3;
    bonds[Pair<string, string>("A", "E")] = 4;
    bonds[Pair<string, string>("A", "F")] = 5;

    cout << myMap[Pair<string, string>("A", "B")] << "\n";
    cout << myMap[Pair<string, string>("B", "A")] << "\n";

    cout << myMap[Pair<string, string>("A", "C")] << "\n";
    cout << myMap[Pair<string, string>("C", "A")] << "\n";

    cout << myMap[Pair<string, string>("A", "D")] << "\n";
    cout << myMap[Pair<string, string>("D", "A")] << "\n";

    cout << myMap[Pair<string, string>("A", "E")] << "\n";
    cout << myMap[Pair<string, string>("E", "A")] << "\n";

    cout << myMap[Pair<string, string>("A", "F")] << "\n";
    cout << myMap[Pair<string, string>("F", "A")] << "\n";

    The outputs are:

    1
    0
    2
    2
    3
    0
    4
    4
    5
    0

    It should not contain 0! but I should have twice the same number like:
    1
    1
    2
    2
    3
    3
    4
    4
    5
    5

    Why is it not as expected? Does anyone know what I'm doing wrong?

    Thank you in advance,

    John
    Florent Garcin, May 10, 2006
    #4
  5. Ian Collins

    John Guest

    Ian Collins wrote:
    > Florent Garcin wrote:
    >
    >>Hello!
    >>
    >>I would like to use the map structure with a key of Pair<string, string>
    >>and an int as the value.
    >>

    >
    > Didn't this come up a few days ago?


    yeah, you are right!

    >
    >
    >>Pair is defined as:
    >>
    >>template <class T1, class T2>
    >>class Pair
    >>{
    >>public:
    >> T1 first;
    >> T2 second;
    >>
    >> Pair()
    >> {
    >> }
    >>
    >> Pair(T1 first, T2 second)
    >> {
    >> this->first = first;
    >> this->second = second;

    >
    > Use initialiser lists.


    what do you mean?

    >
    >> }
    >>
    >> virtual ~Pair()
    >> {
    >> }
    >>
    >> bool operator == (const Pair<T1, T2> p) const

    >
    >
    > Use const Pair&
    >
    >> {
    >> return (first == p.first && second == p.second) || (first == p.second
    >>&& second == p.first);
    >> }
    >>
    >> bool operator < (const Pair<T1, T2> p) const

    >
    >
    > Use const Pair&
    >
    >> {
    >> return !(*this == p) && (first < p.first || (!(p.first < first) &&
    >>second < p.second));
    >> }
    >>
    >>};
    >>
    >>That means the two pairs of, for instance, strings ("A", "B") and ("B",
    >>"A") are equals.
    >>

    >
    > Where are your tests for the above assertion? Add some and you should
    > find your problem.
    >
    John, May 10, 2006
    #5
    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,173
    chris
    Oct 20, 2004
  2. Replies:
    2
    Views:
    539
    klaus hoffmann
    Feb 22, 2006
  3. Replies:
    11
    Views:
    794
    silversurfer
    Jun 21, 2006
  4. Replies:
    1
    Views:
    543
    Daniel Pitts
    Nov 16, 2007
  5. Rui Maciel
    Replies:
    2
    Views:
    2,976
    AndrewDover
    Dec 1, 2009
Loading...

Share This Page