How to make the operator < ( ) work ?

D

ddh

Hi:

I have a class:
class CA
{
private:
int m_val;
};

and another
class CB
{
};


and then I use a std::map to contain the CA & CB pairs:

typedef std::map<CA *, CB *> CMyMap;



Then I get some CA *, CB * to insert into the map:

CA *pA1 = new CA()
CB *pB1 = new CB();
map.insert (std::make_pair(pA1, pB1));

CA *pA2 = new CA();
CB *pB2 = new CB();
map.insert (std::make_pair(pA2, pB2));



But the problem arise, when the second time i insert a pair, it use the
value of the point for comparing. That is to say, if pA2 < pA1, pA2
will be inserted in front of pA1 and vice verse. Which is not what I
want.

So I modify the class CA as:
class CA
{
public:
bool operator < (CA *pA)
{
return m_val < pA->m_val;
}
private:
m_val;
}

But it doesn't work. How can I get to use a user defined compare
function instead the comparion of the raw pointer?

Thank you for your help very much!!
 
R

Rapscallion

ddh said:
I use a std::map to contain the CA & CB pairs:

typedef std::map<CA *, CB *> CMyMap;

Then I get some CA *, CB * to insert into the map:

CA *pA1 = new CA()
CB *pB1 = new CB();

STL uses Value Semantics only (Don't ask why, C++ is not a reasonable
computer language). What you do probably compiles but is against the
design principles of STL. If not semantically wrong do

typedef std::map<CA, CB *> CMyMap;

or even better:

typedef std::map said:
But the problem arise, when the second time i insert a pair, it use the
value of the point for comparing. That is to say, if pA2 < pA1, pA2
will be inserted in front of pA1 and vice verse. Which is not what I
want.

So I modify the class CA as:
class CA
{
public:
bool operator < (CA *pA)

friend bool operator < (const CA& left, const CA& right) {
return left.m_val < right.m_val;
}

{
return m_val < pA->m_val;
}
private:
m_val;
}

But it doesn't work. How can I get to use a user defined compare
function instead the comparion of the raw pointer?

If you really want it (although it's a bad idea):


struct deref_compare {
bool operator< (const CA* left, const CA* right) const {
return *left < *right;
}
}

std::map<CA*, CB*, deref_compare> mymap;
 
R

Rolf Magnus

ddh said:
Hi:

I have a class:
class CA
{
private:
int m_val;
};

and another
class CB
{
};


and then I use a std::map to contain the CA & CB pairs:

typedef std::map<CA *, CB *> CMyMap;

Why pointers?
Then I get some CA *, CB * to insert into the map:

CA *pA1 = new CA()
CB *pB1 = new CB();
map.insert (std::make_pair(pA1, pB1));

CA *pA2 = new CA();
CB *pB2 = new CB();
map.insert (std::make_pair(pA2, pB2));



But the problem arise, when the second time i insert a pair, it use the
value of the point for comparing. That is to say, if pA2 < pA1, pA2
will be inserted in front of pA1 and vice verse. Which is not what I
want.

So I modify the class CA as:
class CA
{
public:
bool operator < (CA *pA)
{
return m_val < pA->m_val;
}
private:
m_val;
}

But it doesn't work.

Of course not. That operator compares a CA with a pointer to CA, not two
pointers. And before you try: No, you cannot make one that compares two
pointers.
How can I get to use a user defined compare function instead the comparion
of the raw pointer?

Use the map's 3rd template argument.
 
P

Peter Koch Larsen

Rapscallion said:
STL uses Value Semantics only (Don't ask why, C++ is not a reasonable
computer language).

Why? Do you find it more reasonable to use values semantics sometimes and
pointer semantics at other times? With the developer having no choice but to
use the choices made by the language implementor.
What you do probably compiles but is against the
design principles of STL. If not semantically wrong do

typedef std::map<CA, CB *> CMyMap;

or even better:

typedef std::map<CA, CB> CMyMap;

That entirely depends on the purpose of the OP. Both are correct, of course.
friend bool operator < (const CA& left, const CA& right) {
return left.m_val < right.m_val;
}



If you really want it (although it's a bad idea):

Why is it a bad idea? If the user believes that pointers were the correct
solution but wants his sort to be made according to value-semantics, this is
a perfectly reasonable way to go.
struct deref_compare {
bool operator< (const CA* left, const CA* right) const {
return *left < *right;
}
}

std::map<CA*, CB*, deref_compare> mymap;
/Peter
 

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

Forum statistics

Threads
474,297
Messages
2,571,530
Members
48,252
Latest member
shilpadhussa

Latest Threads

Top