Overloading one operator in terms of other

Question | Jan 24, 2017 | rparekh 

It is important for the consistency and reusability of code that while overloading an operator we should try to implement it in terms of the other overloaded operator(s).

enter image description here

Let's have an example of buy or sell orders of books. This is what the book buy/sell Order struct looks like:

 struct Order {
  std::string ISBN;  // book's identifier
  double price;      // buy or sell price
  unsigned int quantity; // number of books

  /* ... overloaded operators and 
         other methods go here.. */

To add the quantity of one order to another (of same book and price) the addition-assignment operator (+=) is overloaded for Order struct:

 Order& operator += (const Order& rhs) {
  quantity += rhs.quantity;
  return *this;

Pay attention to the details that the operator '+=' method is is non-const as it is modifying the Order object itself, and it is returning a non-const-reference that allows the chaining of the operator ( c += b += a ) . Say there is a requirement to implement addition operator (+) that returns a new Order object, it should be done in terms of above addition-assignment operator (+=):

const Order operator + (const Order& rhs) const {
  Order copy = *this; // make a copy
  copy += rhs;
  return copy;

Again some details, the operator '+' method is const as it is not modifying the object on which it is called. Its return type is a value because the local variable copy cannot be returned by reference, and the constness of return type prevents the use of '+' expression as modifiable lvalue ( e.g (a+b) = c ).

Here is another case of reusing an overloaded operator's implementation. To match the buy orders with sell orders the Order struct implements equality operator also:

 bool operator == ( const Order& rhs ) const {
   return ( ISBN == rhs.ISBN && 
         std::abs(price-rhs.price) < 0.00001 ); // #include <cmath>

Note that for price comparison it is checked that two floating point numbers (price) are close enough. It is never a good idea to use equality operator (==) for comparing floating point numbers because not all real numbers (numbers with fractional part) can be precisely represented by floating point binary format. The small quantity or error margin to test the closeness of 2 floating point numbers is conventionally called epsilon and can be #defined ( e.g. #define EPSILON 0.00001 ). You can read more about comparing floating point numbers here.

You have to implement inequality operator (!=) on Order that utilizes already overloaded equality operator ( == ). Select the implementation of inequality operator '!=' from given choices that satisfies the requirement: