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

发布于 2025-01-06 15:41:50 字数 1003 浏览 0 评论 0原文

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

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’中的‘operator*’不匹配”。为什么?既然有一个可用的构造函数只接受 2 作为参数,那么它不应该被自动调用吗?如果没有,我该如何让操作员超载才能同时完成这两项工作?

谢谢。

I have the following in my header file:

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

And the following in my main:

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

The first product works, but the second one gives me "error: no match for ‘operator*’ in ‘2 * x’". Why? Since there is a constructor available that takes only the 2 as an argument, shouldn't that be automatically called? If not, how else would I overload the operator to have both of these work?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

为你拒绝所有暧昧 2025-01-13 15:41:50

我不确定为什么编译器不会在 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);
}

如果您在某个内部循环中使用有理数编写高性能代码,这也会表现得更好。

I'm not sure why the compiler will not invoke the single-argument constructor implicitly on 2 in order to produce a rational, but my guess is that the inference mechanism is simply broken when templates are involved.

One workaround (if no one knows how to fix the implicit constructor issue) is to define an additional multiply operators like thus:

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

This will also perform better, if you are writing high-performance code using rationals in an inner loop somewhere.

-小熊_ 2025-01-13 15:41:50
2 * x;

类似于调用 of,

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

2 是一个 int 并且它没有为 constrational重载 operator * 。 &;因此你会得到编译器错误。

正确的做法是:

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

is analogical equivalent to calling of,

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

2 is an int and it doesn't have operator * overloaded for const rational<int>&; thus you get compiler errors.

The correct way is to have:

rational<int> product2 = rational<int>(2) * x; // ok
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文