I'm writing a less than and equal operator function for a class object.
The three variables that are apart of the class are
string firstName;
string LastName;
int age;
To compare them, I wrote this operator function:
bool person::operator < (person b)
{
if (firstName < b.firstName && lastName < b.lastName && age < b.age)
return true;
else
return false;
}
However, my code doesn't work and I don't understand why.
When comparing the objects, priority goes to lastName, firstName, then age.
So, Bill Gates 43 would be technically less than Bill Gates 44.
I hope that is clear enough.
CodePudding user response:
Here's my version of the comparison:
bool person::operator< (const person& b)
{
if (lastName != b.lastName)
{
return lastName < b.lastName;
}
if (firstName != b.firstName)
{
return firstName < b.firstName;
}
return age < b.age;
}
If one field is equal to the object, then the next field is compared. Otherwise the method compares the two fields for less than.
CodePudding user response:
Your comparison logic is wrong. You should write something like:
bool person::operator<(person b) {
if (lastName < b.lastName) {
return true;
} else if (lastName > b.lastName) {
return false;
}
if (firstName < b.firstName) {
return true;
} else if (firstName > b.firstName) {
return false;
}
if (age < b.age) {
return true;
}
return false;
}
CodePudding user response:
Here is a solution using std::tie
It makes writing comparison operators like this very simple and very hard to get wrong.
#include <algorithm>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
struct Person
{
std::string firstName;
std::string lastName;
int age;
bool operator<(const Person &other) const
{
return std::tie(lastName, firstName, age)
< std::tie(other.lastName, other.firstName, other.age);
}
};
void print(const std::string& title, const std::vector<Person> &people)
{
std::cout << title << "\n";
for (const Person &person : people)
{
std::cout << person.lastName << ", "
<< person.firstName << ", "
<< person.age << "\n";
}
}
int main()
{
std::vector<Person> people {
{ "Bill", "Gates", 44 },
{ "Gates", "Bill", 44 },
{ "Back", "Gates", 43 },
{ "Front", "Gates", 44 },
{ "Bill", "Gates", 43 },
{ "Gates", "Bill", 43 },
{ "Back", "Gates", 44 },
{ "Front", "Gates", 43 },
};
print("Before Sort:", people);
std::sort(people.begin(), people.end());
print("After Sort:", people);
return 0;
}
Online example: https://ideone.com/YFnEdB
Output:
Before Sort:
Gates, Bill, 44
Bill, Gates, 44
Gates, Back, 43
Gates, Front, 44
Gates, Bill, 43
Bill, Gates, 43
Gates, Back, 44
Gates, Front, 43
After Sort:
Bill, Gates, 43
Bill, Gates, 44
Gates, Back, 43
Gates, Back, 44
Gates, Bill, 43
Gates, Bill, 44
Gates, Front, 43
Gates, Front, 44
CodePudding user response:
Your code doesn't work for Bill Gates 43
and Bill Gates 44
, because you are only using less than operator here and Bill < Bill
will return false which makes the entire if statement false.
bool person::operator < (const person& b) //Always pass your object as reference
{
if (firstName <= b.firstName && lastName <= b.lastName && age < b.age)
return true;
else
return false;
}
Now it will work for the example you gave. But a better way of doing this would be like this considering you want to compare all three attributes in given order.
bool person::operator < (const person& b)
{
if (lastName != b.lastName)
{
return lastName < b.lastName;
}
else if(firstname != b.firstName)
{
return firstname < b.firstName;
}
else
return age < b.age;
return false;
}