Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

multimap and struct datatype as key

336 views
Skip to first unread message

Ade Adedeji

unread,
May 13, 1999, 3:00:00 AM5/13/99
to

Greetings
I am having some problems inserting elements into a multimap container, when I use a struct datatype as the key. I have tried implementing a comparison function for the struct datatype (I think I have got the logic wrong at this point). I have include some sample code. This example shows that 4 elements are inserted into the container instead of 8 elements in the constructor of MyClass.
Any ideas would be most appreciated

Thanks
Ade


// *************** Structure Datatype******************
struct MyStruct
{
public:
MyStruct(){};
MyStruct(short,short,short,short);
public:
short A;
short B;
short C;
short D;
bool operator()(const MyStruct& x, const MyStruct& y) const
{
return ((x.A < y.A) || (x.B < y.B) || (x.C < y.C) || (x.D < y.D));
}
};

MyStruct::MyStruct(short iA,short iB,short iC,short iD)
{
A = iA;
B = iB ;
C = iC;
D = iD;
}

typedef multimap< MyStruct, double, MyStruct> map_MyStruct;

// **************** Class using STL multimap container *****************
class MyClass
{
public:
MyClass();
virtual ~MyClass();

double Get (const MyStruct& Addr);
void Set (const MyStruct& Addr, double NewValue);
int Count ();

private:
map_MyStruct m_Params;

};

MyClass::MyClass()
{
for (int ii = 1;ii<=2;ii++)
{
MyStruct Address(1,ii,1,1);
Set(Address,10*ii);
Set(Address,11*ii);

MyStruct Address2((ii+1),ii,1,1);
Set(Address2,20*ii);
Set(Address2,22*ii);
}
}

MyClass::~MyClass()
{
}

void MyClass::Set(const MyStruct& Addr, double NewValue)
{
double rTemp;
map_MyStruct::const_iterator i;

i = m_Params.find(Addr);

if ( i == m_Params.end())
{
typedef struct pair<MyStruct,double> PAIR_IF;
PAIR_IF pair1=make_pair(Addr,NewValue);
m_Params.insert( pair1);

rTemp = pair1.second;
}
else
rTemp = (*i).second;

}

double MyClass::Get (const MyStruct& Addr)
{
double rTemp;

map_MyStruct::const_iterator i;

pair<map_MyStruct::const_iterator, map_MyStruct::const_iterator> p =
m_Params.equal_range(Addr);

i = p.first;

if (i != m_Params.end())
rTemp = (*i).second;
else
return -1.0e+38;

return rTemp;
}

int MyClass::Count ()
{
return m_Params.size();
}


///**************** Test Application ************************

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)


{
MyClass Level;

int nTemp = Level.Count();

return 0;
}

-----------------** -- Posted from CodeGuru -- **-----------------
http://www.codeguru.com/ The website for Visual C++ programmers.


Reginald Blue

unread,
May 14, 1999, 3:00:00 AM5/14/99
to
You overloaded the function operator...didn't you want to overload the less
than operator? i.e. shouldn't this:

bool operator()(const MyStruct& x, const MyStruct& y) const
{
return ((x.A < y.A) || (x.B < y.B) || (x.C < y.C) || (x.D < y.D));
}

be this

bool operator<(const MyStruct& x, const MyStruct& y) const


{
return ((x.A < y.A) || (x.B < y.B) || (x.C < y.C) || (x.D < y.D));
}


--
Reginald Blue | Opinions expressed here do not
Natural Language Understanding | necessarily represent those of
Unisys Corporation | my employer.
--------------------------------+-------------------------------
For speech technology solutions,| r...@NOSPAM.trsvr.tr.unisys.com
NL technology,speech application| My email address is wrong, you
development training, see: | need to remove the obvious.
+-------------------------------
http://www.marketplace.unisys.com/nlu/index.html

Ade Adedeji wrote in message <373b8...@209.66.99.126>...

Ade Adedeji

unread,
May 14, 1999, 3:00:00 AM5/14/99
to

Reginald,

Overloading the less than operator was my first option, since thats the default comparison mechanism, it still produces the same error.
This also highlights the following peculiarity( Forgive me if this exposes my limited understanding of STL containers).

I implemented the overloaded less than and function operators. I then set breakpoints in the implemetation, and ran the app in debug.

I tried the following declarations for my multimap container.

1. typedef multimap< MyStruct, double> map_MyStruct;
2. typedef multimap< MyStruct, double, MyStruct> map_MyStruct;

Using declaration 1 produces the following behaviour.
The code steps into the overloaded less than operator, and ignores the function operator.

Using declaration 2 produces the opposite (i.e it steps into the function operator and ignores the less than operator). (Hence the sample code shows overloading of the funtion operator only).

Further comments would be appreciated.

Thanks
Ade

Ilia Tonkovski

unread,
May 17, 1999, 3:00:00 AM5/17/99
to
It's your 'MyClass::Set()' function to blame for that.
As I see things in the case you find a particular key in the map you just
get the value for that first one found.
If you change it like next you'll get your 8 elements.
Cheers

void MyClass::Set(const MyStruct& Addr, double NewValue)
{
double rTemp;
map_MyStruct::const_iterator i;

// i = m_Params.find(Addr);

// if ( i == m_Params.end())


{
typedef struct pair<MyStruct,double> PAIR_IF;
PAIR_IF pair1=make_pair(Addr,NewValue);
m_Params.insert( pair1);

rTemp = pair1.second;
}
// else
// rTemp = (*i).second;

}

Ade Adedeji <aade...@kbc-proc.co.uk> wrote in message
news:373b8...@209.66.99.126...

> typedef multimap< MyStruct, double, MyStruct> map_MyStruct;
>

Ade Adedeji

unread,
May 17, 1999, 3:00:00 AM5/17/99
to

Ilia,
You're correct. This error crept in from my earlier implementation which used a map container instead of a multimap.
I guess what I am trying to confirm is whether the logic in the comparism operator for the struct datatype is correct i.e.

((x.A < y.A) || (x.B < y.B) || (x.C < y.C) || (x.D < y.D));

Thanks
Ade

Mike Enright

unread,
May 17, 1999, 3:00:00 AM5/17/99
to

On 17 May 1999 10:24:11 -0700, "Ade Adedeji" <aade...@kbc-proc.co.uk>
wrote:

>
> Ilia,
> You're correct. This error crept in from my earlier implementation which used a map container instead of a multimap.
> I guess what I am trying to confirm is whether the logic in the comparism operator for the struct datatype is correct i.e.
>
> ((x.A < y.A) || (x.B < y.B) || (x.C < y.C) || (x.D < y.D));

You probably need
(x.A < y.A)
|| (x.A == y.A && ((x.B < y.B)
|| (x.B == y.B) && ((x.C < y.C)
||(x.C == y.C && x.D < y.D)
)
)
)

You need a strict weak ordering for the algorithms in the container to
work properly. I know that the longer expression I've shown here is a
strict weak ordering, and I don't know if your expression gives a
strict weak ordering. My expression is analoguous to the expression
you would write for comparing two 4-digit numbers, digit by digit, to
see which was less.

HTH


--
Mike Enright
mi...@cetasoft.com
(Not speaking for Cetasoft)

0 new messages