覆盖不同数据类型的乘法运算符

Overriding multiplication operator for different datatypes

我创建了以下 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>&);

我想覆盖不同数据类型的乘法函数,例如像这样的 int 和 double

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;
}

我在 Polar 中将函数声明为友元是这样的:

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

然后实现如下:

 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)};  
 }

但是由于在扣除前使用自动,我得到了一个错误。 我不知道如何让 return 类型工作,我不想为每个可能的组合编写一个函数。

有解决这个问题的简单方法吗?

好的,我明白了,我只需要将 class 中的声明从

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

以下内容:

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)>;

使用std::common_type_t>可能会在这里服务。它给你 "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;
}