C++ 模板运算符重载上的自动构造函数调用

C++ Automatic constructor call on template operator overload?

本文关键字:函数调用 运算符 重载 C++      更新时间:2023-10-16

我的头文件中有以下内容:

template<typename T>
class rational {
private:
    T num;
    T denom;
    T gcd(T x, T y);
public:
    rational(T num, T denom);
    rational(T wholeNumber);
    template<typename U>
    friend inline rational<U> operator *(const rational<U> &lhs, const rational<U> &rhs);
}
template<typename T>
rational<T>::rational(T whole) {
    this->num = whole;
    this->denom = 1;
}
template<typename T>
rational<T> operator *(const rational<T> &lhs, const rational<T> &rhs) {
    return rational<T>(lhs.num * rhs.num, lhs.denom * rhs.denom);
}

我的主要内容如下:

rational<int> x(6), y(2);
rational<int> product = y * x;   // this works
rational<int> product2 = 2 * x;  // this doesn't

第一个产品有效,但第二个产品给我"错误:与'2 * x'中的'运算符*'不匹配"。为什么?既然有一个构造函数只接受 2 作为参数,那么不应该自动调用它吗?如果没有,我还能如何使操作员超负荷进行这两项工作?

谢谢。

我不确定为什么编译器不会在 2 上隐式调用单参数构造函数以产生有理数,但我的猜测是,当涉及模板时,推理机制只是被破坏了。

一种解决方法(如果没有人知道如何解决隐式构造函数问题(是定义一个额外的乘法运算符,如下所示:

template<typename T>
rational<T> operator *(const T &lhs, const rational<T> &rhs) {
    return rational<T>(lhs * rhs.num, rhs.denom);
}
template<typename T>
rational<T> operator *(const rational<T> &lhs, const T &rhs) {
    return rational<T>(lhs.num * rhs, lhs.denom);
}

如果您在某处的内部循环中使用 rationals 编写高性能代码,这也将表现得更好。

2 * x;

类比等价于调用,

int::operator*(const rantional<int>&)

2是一个int,它没有operator *重载const rational<int>&;因此你会得到编译器错误。

正确的方法是拥有:

rational<int> product2 = rational<int>(2) * x; // ok