您能否避免数学运算符的多个运算符重载?

Pac*_*uin 0 c++ overloading class operator-overloading

假设我有一个非常简单的 Rational 类,如下所示:

class Rational
{

    int numer;
    int denom;

public:

    Rational(const int& numer, const int& denom) : numer(numer), denom(denom) {}
    void operator*(const Rational& other) { std::cout << "multiply, simple as\n"; }
}
Run Code Online (Sandbox Code Playgroud)

一切都很好。然后说我希望能够将 Rational 类与整数相乘,因此我向该类添加另一个函数:

class Rational
{
    
    int numer;
    int denom;
    
public:
    
    Rational(const int& numer, const int& denom) : numer(numer), denom(denom) {}
    void operator*(const Rational& other) { std::cout << "multiply, simple as\n"; }
    void operator*(const int& other) { std::cout << "some math here\n"; }
}
Run Code Online (Sandbox Code Playgroud)

好吧,没什么大不了的。除了我实际上无法执行以下操作,因为参数的顺序都是错误的:

Rational mine(1, 2);
const Rational result = 2 * mine;
Run Code Online (Sandbox Code Playgroud)

好的,再进行一次迭代,我得到以下结果:

class Rational
{
    
    int numer;
    int denom;
    
public:
    
    Rational(const int& numer, const int& denom) : numer(numer), denom(denom) {}
    void operator*(const Rational& other) { std::cout << "multiply, simple as\n"; }
    void operator*(const int& other) { std::cout << "some math here\n"; }
    friend void operator*(const int& other, const Rational& mine) { std::cout << "even more math here\n"; }
}
Run Code Online (Sandbox Code Playgroud)

我想要找出的是,是否有一种方法可以避免为我希望我的类支持的每个数学运算编写两次相同的函数,这样我就可以使用任何参数来调用它我想要的订单。这很可能就是您在 C++ 类型系统中实现此类事情的方式,但必须为您希望类支持的每个数学运算添加此样板似乎有点烦人。

Art*_*yer 6

具有单个函数的问题是左操作数和右操作数的类型*会有所不同(并且您必须以不同的方式使用它们)。

这可以通过将两个参数类型固定为并创建从到 的Rational隐式转换来解决(无论如何这可能是可取的)。这样,在 中,就会隐式转换为。int xRational x/12 * mine2Rational(2, 1) * mine

这是一个例子:

class Rational
{

    int numer;
    int denom;

public:
    // default argument of denom=1 allows implicit conversion from int
    Rational(int numer, int denom = 1) : numer(numer), denom(denom) {}
    friend Rational operator*(const Rational& l, const Rational& r) {
        std::cout << "Rational(" << l.numer << ", " << l.denom
              << ") * Rational(" << r.numer << ", " << r.denom << ")\n";
        // calculate and return result
    }
    friend Rational operator/(const Rational& l, const Rational& r) { /* ... */ }
    friend bool operator==(const Rational& l, const Rational& r) { /* ... */ }
};
Run Code Online (Sandbox Code Playgroud)