Correct way to overload the multiplication operator in C++ (both directions)

1.4k Views Asked by At

I managed to understand how to implement the overloaded operator as a member function. This way considers the object (instance) is always passed rhs to the operator. In order to get it working, I defined my overloaded operator outside the class. It only works if I define it in the header file (.hpp). Why the compiler ignores it if I add the function to the .cpp file?. A code snippet is as follows:

//class.hpp
#ifndef POINT_H_
#define POINT_H_

template<class T>
class point{
    public:
      point(T&x,T&y);
      point<T> operator*(T& lambda);
      point<T> operator=(const point<T>& P);
      void print();
    private:
        T&x_;
    T&y_;
};
#endif
//class.cpp
#include<iostream>
#include "point.hpp"
template<class T>
point<T>::point(T&x,T&y)
:
x_(x),
y_(y)
{
}

template<class T>
point<T> point<T>::operator*(T& lambda){
    x_*=lambda;
    y_*=lambda;
    return *this;
}

template <class T>
point<T> point<T>::operator = (const point<T> & P){
    this->x_=P.x_;
    this->y_=P.y_;
  return *this;
}

template<class T>
void point<T>::print(){
    std::cout<<"X is "<<this->x_<<" Y is "<<this->y_<<"\n";
}

template class point<int>;
template class point<double>;

template<class T>
  point<T> operator*(T& lambda,point<T>& P)
  {
    return P*lambda;
  }

The last function, shown below, works only if I add it to the header file instead.

template<class T>
  point<T> operator*(T& lambda,point<T>& P)
  {
    return P*lambda;
  }

The main file is

#include<iostream>

#include "point.hpp"

int main(){
    
    double a=3.0;
    double b=4.0;

    point<double> X = point<double>(a,b);
    double m=3.0;
    X=m*X;
    X.print();

    return 0;
}

The compilation error is

no match for 'operator*' (operand types are 'double' and 'point') X=m*X;

If I overload the multiplication operator in the header file instead, the overloading works properly from both directions doublepoint or pointdouble.

1

There are 1 best solutions below

0
On BEST ANSWER

C++ requires declaration of a function in a header (typically .h/.hpp) to use it from different source file (.cpp). So you have to put declaration

template<class T>
point<T> operator*(T& lambda,point<T>& P);

in your inluded header (point.hpp).

By the way, your implementation of the operator is wrong, since computing X * m (or m * X) changes X itself which is generally not desired. So you should implement the operator* as

template<class T>
point<T> point<T>::operator*(T& lambda){
    return point<T>(x_*lambda,y_*lambda);
}

or alternatively you can define operator*= as

template<class T>
point<T>& point<T>::operator*=(T& lambda){
    x_*=lambda;
    y_*=lambda;
    return *this;
}

and do X*=m instead of X=m*X