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:
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?
CodePudding user response:
Okay i got it i only needed to change the declartion in class from
template<typename A, typename B, typename C, typename D>
friend auto operator*(const Polar<A,B>&, const Polar<C,D>&);
To the following:
template<typename A, typename B, typename C, typename D>
friend auto operator*(const Polar<A,B>& p, const Polar<C,D>& w) -> Polar<decltype(p.rad * w.rad),decltype(p.phi w.phi)>;
CodePudding user response:
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."
#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;
}