| | |
Help with < (less than) operator on classes
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
Hi,
I'm trying to use the STL map class to be able to store keys and associated values. I started out using it with keys of pre-existing data types like int, string, etc. and was working fine. I was also able to use it with values of custom classes.
I'm now trying to use it to store keys of custom classes. To do so, it appears to require the creation of the < operator (presumably so that the map can sort the keys).
My question is this - what is the proper code inside the < operator? Below is what I have, (and it compiles and seems to work), but I'm not sure it makes sense. How would it need to change if I had other data types inside my KeyObj class as well? Also, should I somehow account for the fact that if lastName is blank on one object and firstName is blank on the other object being compared, that they might be considered equal? - would I handle that by putting a separator in between when comparing?)
------------------------
Searching for FRED JONES:
MR. FRED JONES
I'm trying to use the STL map class to be able to store keys and associated values. I started out using it with keys of pre-existing data types like int, string, etc. and was working fine. I was also able to use it with values of custom classes.
I'm now trying to use it to store keys of custom classes. To do so, it appears to require the creation of the < operator (presumably so that the map can sort the keys).
My question is this - what is the proper code inside the < operator? Below is what I have, (and it compiles and seems to work), but I'm not sure it makes sense. How would it need to change if I had other data types inside my KeyObj class as well? Also, should I somehow account for the fact that if lastName is blank on one object and firstName is blank on the other object being compared, that they might be considered equal? - would I handle that by putting a separator in between when comparing?)
C++ Syntax (Toggle Plain Text)
class KeyObj { public: string lastName; string firstName; bool operator< (const KeyObj &compare) { return lastName+firstName < compare.lastName+compare.firstName; } }; bool operator< (const KeyObj &source, const KeyObj &compare) { return source.lastName+source.firstName < compare.lastName+compare.firstName; } int main( int argc, char * argv[] ) { map<KeyObj,string> myMap; KeyObj k; k.lastName="JONES"; k.firstName="BOB"; myMap[k] = "MR. BOB JONES"; KeyObj k2; k2.lastName="JONES"; k2.firstName="FRED"; myMap[k2] = "MR. FRED JONES"; cout<<"Searching for FRED JONES:"<<endl; KeyObj test; test.lastName="JONES"; test.firstName="FRED"; if ( myMap.find(test) != myMap.end() ) { cout<<myMap[test]<<endl; } else cout<<"COULDN't FIND IT"<<endl;
Searching for FRED JONES:
MR. FRED JONES
Last edited by winbatch; May 11th, 2005 at 9:41 am. Reason: Code tags
Code tags don't help much if your code isn't formatted to begin with.
>what is the proper code inside the < operator?
That depends on the needs of the class. Does it make more sense to compare by first name, last name, or both? How you define operator< depends heavily on that decision. However, once it's made, the implementation is somewhat trivial in your case:
>what is the proper code inside the < operator?
That depends on the needs of the class. Does it make more sense to compare by first name, last name, or both? How you define operator< depends heavily on that decision. However, once it's made, the implementation is somewhat trivial in your case:
C++ Syntax (Toggle Plain Text)
#include <iostream> #include <string> #include <map> class Person { std::string _first, _last; public: Person(const std::string& first, const std::string& last) : _first(first), _last(last) {} bool operator<(const Person& p) const { //return _last < p._last; //return _first < p._first; return _last + _first < p._last + p._first; } friend std::ostream& operator<<(std::ostream& out, const Person& p) { return out<< p._last <<", "<< p._first; } }; int main() { std::map<Person, int> m; ++m[Person("John", "Doe")]; ++m[Person("Jane", "Doe")]; ++m[Person("", "Doe")]; ++m[Person("John", "Doe")]; ++m[Person("John", "")]; std::map<Person, int>::iterator it = m.begin(); while (it != m.end()) { std::cout<< it->first <<" -- "<< it->second <<std::endl; ++it; } }
I'm here to prove you wrong.
Narue,
Assuming I want to compare by both last and first (I created this as a trivial example - I have many more fields, all of which are important) - do I need to deal with an 'empty' last or an 'empty' first which might make two items equal? (or even better a last name of "AB" with a first name of "CD" vs. a last name of "A" and a first name of "BCD"..
(ie would lastname + "-" + firstname < other.lastname + "-" + other.firstname )
make it 'safer'?
Also, in the syntax you are using for inserting into the map(which I've never seen before), what int is being assigned for the value?
Assuming I want to compare by both last and first (I created this as a trivial example - I have many more fields, all of which are important) - do I need to deal with an 'empty' last or an 'empty' first which might make two items equal? (or even better a last name of "AB" with a first name of "CD" vs. a last name of "A" and a first name of "BCD"..
(ie would lastname + "-" + firstname < other.lastname + "-" + other.firstname )
make it 'safer'?
Also, in the syntax you are using for inserting into the map(which I've never seen before), what int is being assigned for the value?
•
•
•
•
Originally Posted by winbatch
Also, in the syntax you are using for inserting into the map(which I've never seen before), what int is being assigned for the value?
>do I need to deal with an 'empty' last or an 'empty' first which might make two items equal?
The only situation where this would be true is if the last name is the same and the first name is empty for both objects (or vice versa). Of course, they would be equal and it's hard to figure out a way to avoid that since you would basically be saying "Strings that are equal are equal, except...", which is nonsensical.
>or even better a last name of "AB" with a first name of "CD" vs. a last name of "A" and a first name of "BCD".
Now that makes more sense, and you're on the right track for how to solve it.
>what int is being assigned for the value?
If not value is given, it defaults to T(), which is 0 for int. So for each name added, I'm incrementing the value starting with 0.
The only situation where this would be true is if the last name is the same and the first name is empty for both objects (or vice versa). Of course, they would be equal and it's hard to figure out a way to avoid that since you would basically be saying "Strings that are equal are equal, except...", which is nonsensical.
>or even better a last name of "AB" with a first name of "CD" vs. a last name of "A" and a first name of "BCD".
Now that makes more sense, and you're on the right track for how to solve it.
>what int is being assigned for the value?
If not value is given, it defaults to T(), which is 0 for int. So for each name added, I'm incrementing the value starting with 0.
I'm here to prove you wrong.
![]() |
Similar Threads
Other Threads in the C++ Forum
- Previous Thread: fastest compiler
- Next Thread: string input not working as expected
| Thread Tools | Search this Thread |
api array arrays based beginner binary bitmap c++ c/c++ calculator char class classes code compile compiler console conversion count delete deploy desktop directshow dll download dynamic dynamiccharacterarray encryption error file forms fstream function functions game getline givemetehcodez google graph gui homeworkhelp homeworkhelper iamthwee ifstream input int integer java lib linkedlist linker linux list loop looping loops map math matrix memory news node output parameter pointer problem program programming project proxy python read recursion recursive reference return rpg string strings struct temperature template templates test text text-file tree unix url variable vector video visual visualstudio win32 windows winsock word wordfrequency wxwidgets






