### Search

Because the comparison operators are all binary operators that do not modify their left operands, we will make our overloaded comparison operators friend functions.

Here’s an example Car class with an overloaded operator== and operator!=.

The code here should be straightforward. Because the result of operator!= is the opposite of operator==, we define operator!= in terms of operator==, which helps keep things simpler, more error free, and reduces the amount of code we have to write.

What about operator< and operator>? What would it mean for a Car to be greater or less than another Car? We typically don’t think about cars this way. Since the results of operator< and operator> would not be immediately intuitive, it may be better to leave these operators undefined.

Recommendation: Don’t define overloaded operators that don’t make sense for your class.

However, there is one common exception to the above recommendation. What if we wanted to sort a list of Cars? In such a case, we might want to overload the comparison operators to return the member (or members) you’re most likely to want to sort on. For example, an overloaded operator< for Cars might sort based on make and model alphabetically.

Some of the container classes in the standard library (classes that hold sets of other classes) require an overloaded operator< so they can keep the elements sorted.

Here’s a different example with an overloaded operator>, operator<, operator>=, and operator<=:

This is also pretty straightforward.

Note that there is some redundancy here as well. operator> and operator<= are logical opposites, so one could be defined in terms of the other. operator< and operator>= are also logical opposites, and one could be defined in terms of the other. In this case, I chose not to do so because the function definitions are so simple, and the comparison operator in the function name line up nicely with the comparison operator in the return statement.

Quiz time

1) For the Cents example above, rewrite operators < and <= in terms of other overloaded operators.

Show Solution

2) Add an overloaded operator<< and operator< to the Car class at the top of the lesson so that the following program compiles:

This program should produce the following output:

```(Honda, Accord)
(Honda, Civic)
(Toyota, Camry)
(Toyota, Corolla)
```

Show Solution

• Jack

Q2. my version of overloaded operator< function.

• Hi Jack!

Your code will work in most cases. Not all

c1: hond acivic
c2: honda civic

On top of that, your code constructs 2 temporary strings, which is slow.

• Alex

In case anyone is interested. I used the compare function of string and it worked.

• Hi Alex!

* Initialize your variables with uniform initialization. You used copy initialization.
* You're comparing the models even if @model_comp is not used.

• Marcos O.

Hi!

Regarding Quiz(2), in the solution why are the == and != operators overloaded? Aren't the values they compare already resolved to pseudo-fundamental strings when operator < is used? Also wouldn't it be preferable for operator< to be a member function of Car as the left most operand is of type Car?

My solution to Q(2):

• > why are the == and != operators overloaded?
They're not used in this quiz, I don't know why Alex added them. It's worth mentioning that C++ doesn't offer default operator== and operator!=. If you want to compare objects of your class, you need to define those operators manually.

> Aren't the values they compare already resolved to pseudo-fundamental strings when operator < is used?
I'm not sure what you mean. @Car::operator< doesn't make use of @Car::operator== or @Car::operator!=. It used @std::string's operators.

> Also wouldn't it be preferable for operator< to be a member function of Car as the left most operand is of type Car?
Lesson 9.4 says not to do so, because with a non-member function it'd be easier to swap the order of the parameters, which doesn't matter in this case.

> My solution
I'm skipping @main, because you copied it.
* Line 4, 5, 9: Initialize your variables with uniform initialization. @m_make and @m_model will be initialized anyway, but if you initialize everything, you won't forget to when you need it.

• Alex

The overloaded operator== and operator!= were in the original Car program that the quiz question is extending. Even though they're not used, there's no harm in having them there since it's just a copy/paste from above.

• Marcos O.

Ah k, thanks Alex!

• Marcos O.

>...C++ doesn't offer default operator== and operator!=. If you want to compare objects of your class, you need to define those operators manually.
If c++ doesnt offer default == or != then how are they used for

where the operator isn't defined or a simpler case

Int in the above example is just to indicate type of x and y, not be correct code.
And what do you define as "default", is the std library and string library "default"? Is it because we arent comparing the objects of defined class  (which would require overloading operator) instead the string objects within?

>It used @std::string's operators
Thank you for confirming, thats exactly what I meant, I just wanted to make sure.

>Lesson 9.4 says not to do so, because with a non-member function it'd be easier to swap the order of the parameters, which doesn't matter in this case.
Isnt this case specifically to compare an object of the same type with an object of our defined type as reference? Isn't a case where your defined object is the reference one of the specific times to use a member function?

>* Line 4, 5, 9: Initialize your variables with uniform initialization
Line 4, 5: I thought we werent supposed to initialize a variable both at definition and construction. Is that only if initialized with a value?
Line 9: VS2013 doesn't seem to like uniform initialization and often throws me errors when I try. Do you have any tips or suggestions around these errors?

Thank you for your help. I would have further appreciated if you left your assumption about me copying @main out.

• > And what do you define as "default"
Types you write yourself. int, double and other native types have operators. @std::string is a class, it has those operators, whoever wrote the @std::string class that's being used on your system wrote those operators.

> Isnt this case specifically to compare an object of the same type [...]
Sorry, I'm having a hard time trying to understand what you're asking.

>  I thought we werent supposed to initialize a variable both at definition and construction
I don't know what you're referring to. Mind sharing the lesson?
Initialize all variables. If possible, to a specific (0) value. @std::string has a default constructor, so just use empty curly brackets.

> VS2013 doesn't seem to like uniform initialization and often throws me errors when I try
If this happens sometimes, but not always, you're doing something wrong (Or there's a compiler bug, which is unlikely). If it never allows uniform initialization, upgrade your compiler.

> I would have further appreciated if you left your assumption about me copying @main
Initialize @v instead of manually pushing all elements. Also, uniform initialization.

• Khang

I think the right spelling is "nickel" not "nickle".

• Alex

Typos fixed. Thanks for pointing that out.

• i don't understand in second quiz some answers make the program crash such as doing this:
return (c1.m_make < c2.m_make) || (c1.m_model < c2.m_model)
if one or the other is alphabetically out of order sort it , even if it won't do exactly what is required.
does this have to do something with the iterators ?

• Hi Michael!

Your @operator< is invalid, because it allows car A to be smaller than car B, but at the same time B is smaller than A.

Depending on the implementation of @std::sort, this could cause infinite loops, exceptions or crashes.