我的头文件中有以下内容:
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作为参数,不应该自动调用吗?如果没有,我怎么重载操作员让这两个工作?
感谢。
答案 0 :(得分:0)
我不确定为什么编译器不会在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);
}
如果您在某个内部循环中使用有理数编写高性能代码,这也会表现得更好。
答案 1 :(得分:-1)
2 * x;
类似于调用,
int::operator*(const rantional<int>&)
2
是int
,operator *
没有重载const rational<int>&
;因此你会遇到编译器错误。
正确的方法是:
rational<int> product2 = rational<int>(2) * x; // ok