Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Overriding multiplication operator for different datatypes

I created the following class

template<typename T, typename S>
class Polar{

private:
  T rad;
  S phi;

public:
  Polar(T r, S p) : rad{r}, phi{p} {}
  template<typename A, typename B> 
  friend std::ostream& operator<<(std::ostream&, const Polar<A,B>&);

And i want to override the multiplication function for different datatypes for example int and double like this

int main() {
   Polar<int,int> p{2,3};
   Polar<int,int> w{4,5};
   Polar<float,double> z{6,7};

   std::cout << p*w << std::endl;
   std::cout << p*z << std::endl;
  return 0;
}

I declared the function as a friend in Polar like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

 template<typename A, typename B, typename C, typename D> 
 friend auto operator*(const Polar<A,B>&, const Polar<C,D>&);

And then implemented it as the following:

 template<typename A, typename B, typename C, typename D>
 auto operator*(const Polar<A,B>& p, const Polar<C,D>& w) -> Polar<decltype(p.rad * w.rad),decltype(p.phi + w.phi)>
 {
   return Polar<decltype(p.rad * w.rad),decltype(p.phi + w.phi)> {(p.rad * w.rad),(p.phi + w.phi)};  
 }

But i am getting an error because of using auto before deduction.
I dont know how to get the return-type to work and i dont want to write a function for each possible combination.

Is there an easy way to tackle this?

>Solution :

Using std::common_type_t> may serve here. It gives you "the common type among all types T…, that is the type all T… can be implicitly converted to."

[Demo]

#include <iostream>  // cout
#include <ostream>
#include <type_traits>  // common_type_t

template<typename T, typename S>
class Polar
{
public:
    Polar(T r, S p) : rad{r}, phi{p} {}

    template<typename A, typename B> 
    friend std::ostream& operator<<(std::ostream&, const Polar<A, B>&);
    
    template<typename A, typename B, typename C, typename D>
    friend auto operator*(const Polar<A, B>& p, const Polar<C, D>& w);
private:
    T rad;
    S phi;
};

template<typename A, typename B> 
std::ostream& operator<<(std::ostream& os, const Polar<A, B>& p)
{
    return os << "(" << p.rad << ", " << p.phi << ")";
}

template<typename A, typename B, typename C, typename D>
auto operator*(const Polar<A, B>& p, const Polar<C, D>& w)
{
    using RT = std::common_type_t<A, C>;
    using RS = std::common_type_t<B, D>;
    
    return Polar<RT, RS>{p.rad * w.rad, p.phi + w.phi};
}

int main()
{
   Polar<int, int> p{2, 3};
   Polar<int, int> w{4, 5};
   Polar<float, double> z{6.5, 7.5};

   std::cout << p* w << std::endl;
   std::cout << p*z << std::endl;
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading