473,770 Members | 7,142 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Is this a valid less than operator for a map?

I have a class that already has == and != operators that I want to use
in a map that uses my class (not a pointer to the class) as the key.
To do this I need a < operator. Is this a valid less than operator to
use in this case?
bool MyClass::operat or<(const MyClass &other) const
{
if (*this == other) return false;
return (this < &other);
}

I can declare and use a map variable using this operator

std::map<MyClas s,std::string> m_MyClassCache;

I am worried that if the map is sorted and then something is added and
the map is reallocated by copying to a new array the previosly sorted
items may no longer be sorted. Is this likely to be a problem?

Thanks
Aug 22 '08 #1
12 5767
On 22 Aug., 12:51, "dimsttho...@ya hoo.com" <dimsttho...@ya hoo.com>
wrote:
I have a class that already has == and != operators that I want to use
in a map that uses my class (not a pointer to the class) as the key.
To do this I need a < operator. Is this a valid less than operator to
use in this case?

bool MyClass::operat or<(const MyClass &other) const
{
* * * * if (*this == other) return false;
* * * * return (this < &other);

}
No - it is not valid. Swapping the elements around will change the
predicate so that you for two elements could have a < b and b < a at
different times.

/Peter
Aug 22 '08 #2
Hi,

Your key to the map sorts on the memory address i.e. pointer to it (usually
this is not what you want). Here is a key from a map i.e. the map[ Key ] =
Data; (The map only needs the < operator).
Example:

class MMyClass
{
private:
std::string Key1; // Part one of the key
std::string Key2; // Part two of the key
std::string Key3; // Part three of the key

public:
MMyClass( const std::string& Key1, const std::string& Key2, const
std::string& Key3):
Key1( Key1 ),
Key2( Key2 ),
Key3( Key3 )
{
}
bool operator<( const MMyClass& MyClass ) const
{
if( Key1 < MyClass.Key1 ) return true;
else if( Key1 == MyClass.Key1 )
{
if( Key2 < MyClass.Key2 ) return true;
else if( Key2 == MyClass.Key2 )
{
return Key3 < MyClass.Key3;
}
}

return false;
}
};


Regards, Ron AF Greve

http://www.InformationSuperHighway.eu

<di*********@ya hoo.comwrote in message
news:eb******** *************** ***********@y21 g2000hsf.google groups.com...
>I have a class that already has == and != operators that I want to use
in a map that uses my class (not a pointer to the class) as the key.
To do this I need a < operator. Is this a valid less than operator to
use in this case?
bool MyClass::operat or<(const MyClass &other) const
{
if (*this == other) return false;
return (this < &other);
}

I can declare and use a map variable using this operator

std::map<MyClas s,std::stringm_ MyClassCache;

I am worried that if the map is sorted and then something is added and
the map is reallocated by copying to a new array the previosly sorted
items may no longer be sorted. Is this likely to be a problem?

Thanks

Aug 22 '08 #3
On 22 Aug, 12:18, peter koch <peter.koch.lar ...@gmail.comwr ote:
On 22 Aug., 12:51, "dimsttho...@ya hoo.com" <dimsttho...@ya hoo.com>
wrote:
I have a class that already has == and != operators that I want to use
in a map that uses my class (not a pointer to the class) as the key.
To do this I need a < operator. Is this a valid less than operator to
use in this case?
bool MyClass::operat or<(const MyClass &other) const
{
* * * * if (*this == other) return false;
* * * * return (this < &other);
}

No - it is not valid. Swapping the elements around will change the
predicate so that you for two elements could have a < b and b < a at
different times.
I thought it was a bit dodgy. I have come up with a better solution
using an instance variable (which is not compared in the == operator):

class MyClass
{
...

private:
unsigned long m_instance;
static unsigned long m_instanceCount ;
};

unsigned long MyClass::m_inst anceCount = 0;

MyClass::MyClas s() : m_instance(m_in stanceCount++)
{
}

MyClass::MyClas s(double x, double y) : m_instance(m_in stanceCount++)
{
}

MyClass::MyClas s(const MyClass& rhs) : m_instance(rhs. m_instance)
{
}

MyClass& MyClass::operat or=(const MyClass& rhs)
{
if (this != &rhs)
{
...
m_instance = rhs.m_instance;
}
return *this;
}

bool MyClass::operat or<(const MyClass &other) const
{
if (*this == other) return false;
return (m_instance < other.m_instanc e);
}

Aug 22 '08 #4
On 22 Aug, 12:37, "Ron AF Greve" <ron@localhostw rote:
Hi,

Your key to the map sorts on the memory address i.e. pointer to it (usually
this is not what you want). Here is a key from a map i.e. the map[ Key ] =
Data; (The map only needs the < operator).
Example:

class MMyClass
{
* private:
* * std::string Key1; // Part one of the key
* * std::string Key2; // Part two of the key
* * std::string Key3; // Part three of the key

* public:
* * MMyClass( *const std::string& Key1, const std::string& Key2, const
std::string& Key3):
* * * Key1( Key1 ),
* * * Key2( Key2 ),
* * * Key3( Key3 )
* * {
* * }
* * bool operator<( const MMyClass& MyClass ) const
* * {
* * * if( Key1 < MyClass.Key1 ) return true;
* * * else if( Key1 == MyClass.Key1 )
* * * {
* * * * if( Key2 < MyClass.Key2 ) return true;
* * * * else if( Key2 == MyClass.Key2 )
* * * * {
* * * * * return Key3 < MyClass.Key3;
* * * * }
* * * }

* * * return false;
* * }

};

Regards, Ron AF Greve

Yes, but the problem is the class I am using has a lot of member data
and already has an == operator and I wanted to avoid having to write a
fully fledged < operator. See my other reply.

Aug 22 '08 #5
On 22 Aug, 12:41, "dimsttho...@ya hoo.com" <dimsttho...@ya hoo.com>
wrote:
On 22 Aug, 12:18, peter koch <peter.koch.lar ...@gmail.comwr ote:


On 22 Aug., 12:51, "dimsttho...@ya hoo.com" <dimsttho...@ya hoo.com>
wrote:
I have a class that already has == and != operators that I wantto use
in a map that uses my class (not a pointer to the class) as the key.
To do this I need a < operator. Is this a valid less than operator to
use in this case?
bool MyClass::operat or<(const MyClass &other) const
{
* * * * if (*this == other) return false;
* * * * return (this < &other);
}
No - it is not valid. Swapping the elements around will change the
predicate so that you for two elements could have a < b and b < a at
different times.

I thought it was a bit dodgy. I have come up with a better solution
using an instance variable (which is not compared in the == operator):

class MyClass
{
...

private:
* * * * unsigned long m_instance;
* * * * static unsigned long m_instanceCount ;

};

unsigned long MyClass::m_inst anceCount = 0;

MyClass::MyClas s() : m_instance(m_in stanceCount++)
{

}

MyClass::MyClas s(double x, double y) : m_instance(m_in stanceCount++)
{

}

MyClass::MyClas s(const MyClass& rhs) : m_instance(rhs. m_instance)
{

}

MyClass& MyClass::operat or=(const MyClass& rhs)
{
* * * * if (this != &rhs)
* * * * {
* * * * * * * * ...
* * * * * * * * m_instance * *= rhs.m_instance;
* * * * }
* * * * return *this;

}

bool MyClass::operat or<(const MyClass &other) const
{
* * * * if (*this == other) return false;
* * * * return (m_instance < other.m_instanc e);

}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -
This solution doesn't work either as the map doesn't compare every
item when inserting new items, I assume it does some kind of binary
search based on the sorted list (which is the whole point of a map!).
Looks like I will have to implement a proper less than operator.
Aug 22 '08 #6
di*********@yah oo.com wrote:
On 22 Aug, 12:41, "dimsttho...@ya hoo.com" <dimsttho...@ya hoo.com>
wrote:
>On 22 Aug, 12:18, peter koch <peter.koch.lar ...@gmail.comwr ote:


>>On 22 Aug., 12:51, "dimsttho...@ya hoo.com" <dimsttho...@ya hoo.com>
wrote:
I have a class that already has == and != operators that I want to use
in a map that uses my class (not a pointer to the class) as the key.
To do this I need a < operator. Is this a valid less than operator to
use in this case?
bool MyClass::operat or<(const MyClass &other) const
{
if (*this == other) return false;
return (this < &other);
}
No - it is not valid. Swapping the elements around will change the
predicate so that you for two elements could have a < b and b < a at
different times.
I thought it was a bit dodgy. I have come up with a better solution
using an instance variable (which is not compared in the == operator):

class MyClass
{
...

private:
unsigned long m_instance;
static unsigned long m_instanceCount ;

};

unsigned long MyClass::m_inst anceCount = 0;

MyClass::MyCla ss() : m_instance(m_in stanceCount++)
{

}

MyClass::MyCla ss(double x, double y) : m_instance(m_in stanceCount++)
{

}

MyClass::MyCla ss(const MyClass& rhs) : m_instance(rhs. m_instance)
{

}

MyClass& MyClass::operat or=(const MyClass& rhs)
{
if (this != &rhs)
Remove the above line with if
> {
...
m_instance = rhs.m_instance;
}
return *this;

}

bool MyClass::operat or<(const MyClass &other) const
{
if (*this == other) return false;
Remove the above line with if
> return (m_instance < other.m_instanc e);


This solution doesn't work either as the map doesn't compare every
item when inserting new items, I assume it does some kind of binary
search based on the sorted list (which is the whole point of a map!).
Looks like I will have to implement a proper less than operator.

Why it doesn't work? It should work
Do you have a compilable example?
Aug 22 '08 #7
Hi,

It is a lot of work :-(. Since I often access databases I actually got tired
of writing a key class everytime so I sort of created a simple javascript
that does some of the work. (It is just a quick script and not bugfree but
does the job for me, currently only supports strings though).

http://informationsuperhighway.eu/genkey.html
Regards, Ron AF Greve

http://www.InformationSuperHighway.eu

<di*********@ya hoo.comwrote in message
news:de******** *************** ***********@a1g 2000hsb.googleg roups.com...
On 22 Aug, 12:37, "Ron AF Greve" <ron@localhostw rote:
Hi,

Your key to the map sorts on the memory address i.e. pointer to it
(usually
this is not what you want). Here is a key from a map i.e. the map[ Key ] =
Data; (The map only needs the < operator).
Example:

class MMyClass
{
private:
std::string Key1; // Part one of the key
std::string Key2; // Part two of the key
std::string Key3; // Part three of the key

public:
MMyClass( const std::string& Key1, const std::string& Key2, const
std::string& Key3):
Key1( Key1 ),
Key2( Key2 ),
Key3( Key3 )
{
}
bool operator<( const MMyClass& MyClass ) const
{
if( Key1 < MyClass.Key1 ) return true;
else if( Key1 == MyClass.Key1 )
{
if( Key2 < MyClass.Key2 ) return true;
else if( Key2 == MyClass.Key2 )
{
return Key3 < MyClass.Key3;
}
}

return false;
}

};

Regards, Ron AF Greve

Yes, but the problem is the class I am using has a lot of member data
and already has an == operator and I wanted to avoid having to write a
fully fledged < operator. See my other reply.
Aug 22 '08 #8
On Aug 22, 4:18*am, peter koch <peter.koch.lar ...@gmail.comwr ote:
On 22 Aug., 12:51, "dimsttho...@ya hoo.com" <dimsttho...@ya hoo.com>
wrote:
I have a class that already has == and != operators that I want to use
in a map that uses my class (not a pointer to the class) as the key.
To do this I need a < operator. Is this a valid less than operator to
use in this case?
bool MyClass::operat or<(const MyClass &other) const
{
* * * * if (*this == other) return false;
* * * * return (this < &other);
}

No - it is not valid. Swapping the elements around will change the
predicate so that you for two elements could have a < b and b < a at
different times.
I don't see why this operator<() would be invalid - that is, why it
would not produce a total ordering of MyClass elements. After all,
swapping the left and right elements would effectively also swap the
values of "other" and "this". And presumably whenever

this < &other

is true than

&other < this

will be false. Just as, whenever:

other == *this

is true, then

*this == other

is certain to be true as well.

Admittedly the operator<() here doesn't seem to have any practical
value. Nevertheless it does appear to me - to be valid.

Greg

Aug 22 '08 #9
On 2008-08-22 08:13:31 -0400, "di*********@ya hoo.com"
<di*********@ya hoo.comsaid:
>
This solution doesn't work either as the map doesn't compare every
item when inserting new items, I assume it does some kind of binary
search based on the sorted list (which is the whole point of a map!).
Looks like I will have to implement a proper less than operator.
Good idea. If you have to fight with the design, chances are you're
doing something wrong.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Aug 22 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2189
by: news | last post by:
I have lines of code that look like this: while ($row2sx = mysql_fetch_array($result2sx)) { Now that's the way I've always learned to create an array from a mySQL querey. I just started trying the Zend Studio (and to be honest, except for the debugger I'm seeing that it has less features than EditPlus.) And the debugger calls all my WHERE() functions bugged because I'm
6
1532
by: Dave Theese | last post by:
Please see questions in the code below... Thanks! #include <iostream> using namespace std; class foo_class { public: foo_class() {cout << "Constructing..." << endl;}
23
1929
by: James Aguilar | last post by:
Someone showed me something today that I didn't understand. This doesn't seem like it should be valid C++. Specifically, I don't understand how the commas are accepted after the function 'fprintf'. What effect do they have in those parenthesis? I understand how the or is useful and why never to do it, I'm really just asking about that construction "(fprintf(stderr, "Can't open file.\n"), exit(0), 1))". ---- CODE ----
5
10934
by: lallous | last post by:
Hello How can I define an operator for such: bool operator<(my_class *l,my_class *r) { return l->_attribute < r->_attribute; } So that I can use with std::less, as:
11
8795
by: Martin Jørgensen | last post by:
Hi, - - - - - - - - - - - - - - - #include <iostream> #include <string> #include <map> using namespace std; int main() {
60
3883
by: andrew queisser | last post by:
Is this code below valid C++? I'd like to use this construct but I'm not sure if it'll be portable. struct foo { char x; }; struct bar { char sameSizeAsFooX;
16
5088
by: Cory Nelson | last post by:
Does anyone know how std::set prevents duplicates using only std::less? I've tried looking through a couple of the STL implementations and their code is pretty unreadable (to allow for different compilers, I guess).
3
2285
by: ek | last post by:
I have the following class: template<typename I> class test { public: test(I i) : pp(i) {} I getpp() const { return pp; }
9
2276
by: Marijn | last post by:
Hey everybody, I was wondering if the following would be a valid JavaScript assignment vor a variable and if anybody knows this to work in IE6 or lower? var someVar = (typeof(someVar) === Object) ? this : getVar(); function getVar(){ alert('getVar() called');
0
10230
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10058
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10004
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9870
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8886
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7416
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5313
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3972
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2817
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.