Я очень смущен тем, как получить аргумент шаблона возвращаемого объекта при простой перегрузке оператора.

Это мой код:

#include <iostream>

template <typename T>
class numeric {
    public:
        numeric(): value_{0} {}
        numeric(T value): value_{value} {} 
        numeric(const numeric& other) { value_ = other.value_; }

        ~numeric() {}

        template <typename O> 
        numeric<T> operator+(const numeric<O>& other) {
            return numeric<T>(value_ + other.value_); 
        }

        friend std::ostream& operator<<
        (std::ostream& os, const numeric& other) {
            os << other.value_;
            return os; 
        }
   private:
        T value_;
};

int main() {
     numeric<int> x = 10;
     numeric<float> y = 5.5;
     
     std::cout << (x + y); 

     return 0;
}

И моим желаемым результатом было распечатать 15.5 на консоли.

c++
1
Desmond Gold 12 Фев 2021 в 04:43

1 ответ

Лучший ответ

Даже если у вашей попытки не было проблем с доступом к закрытому члену другого класса - что можно было бы обойти, сделав этот член общедоступным - у вас будет проблема с несогласованным поведением, когда x + y приводит к 15, потому что тип результата будет numeric<int>. y + x даст желаемые 15.5.

Вы можете исправить как проблему доступа, так и тип возвращаемого значения, используя шаблон перегрузки дружественного оператора. Используйте параметр типа шаблона для обоих операндов. Возвратная обертка общего типа. Вам нужно будет определить его вне шаблона класса, чтобы вы не получали разные определения для каждого экземпляра шаблона класса:

template <typename T>
class numeric {
...
    template<class L, class R>
    friend auto operator+(const numeric<L>&, const numeric<R>&);
...
};

template<class L, class R>
auto operator+(const numeric<L>& l, const numeric<R>& r) {
    using common_type = numeric<std::common_type_t<L, R>>;
    return common_type(l.value_ + r.value_); 
}
2
eerorika 12 Фев 2021 в 02:24