C ++ Автоматический вызов конструктора при перегрузке оператора шаблона? - PullRequest
2 голосов
/ 17 февраля 2012

В моем заголовочном файле есть следующее:

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 * х ». Зачем? Поскольку имеется конструктор, который принимает в качестве аргумента только 2, разве это не должно вызываться автоматически? Если нет, как еще мне перегрузить оператор, чтобы они оба работали?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 17 февраля 2012
2 * x;

аналогично вызову,

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

2 является int и не перегружено operator * для const rational<int>&;Таким образом, вы получаете ошибки компилятора.

Правильный путь - иметь:

rational<int> product2 = rational<int>(2) * x; // ok
0 голосов
/ 17 февраля 2012

Я не уверен, почему компилятор не будет вызывать конструктор с одним аргументом неявно в 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);
}

Это также будет работать лучше, если вы пишетевысокопроизводительный код, использующий рациональные числа во внутреннем цикле где-то.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...