C++ Operator Overloading : Multiplication of User Defined Type by floating point values

789 views Asked by At

I am trying to implement multiplication operators (operator*) for 4 situations.

Imagine I have a class rain.

namespace manchester {

    namespace manchester_private_dont_use_this {

        template<typename T>
        class rain
        {

        public:
            rain(T initial_rain)
                : m_rain(initial_rain)
            {
            }

        private:
             T m_quantity_of_rain;
        };

    }

} //namespace manchester

Assume this class is declared inside a private namespace. typedef rain<float> rainf; and typedef rain<double> raind expose the functionality of this class inside a non-private namespace. By private namespace I mean another nested namespace which is called something like namespace rainprivate_do_not_use_me. (In the example I actually added two namespaces to explain what I'm talking about, but that's not really important.) That's the best I could come up with to prevent the end user (me) from trying to create a rain<int> which doesn't make much sense, since rain is measured in litres., and therefore we can have non-integer quantities.

Anyway, I was to implement operator* like I said, for the case of multiplying a quantity of rain by both a float and a double. Am I correct in assuming that since these types can be implicitly converted, I only need to implement an operator where the rhs variable is a double and where the lhs variable is a double. (By double I actually mean the type, T.)

Again, I am guessing here - see my previous question about unary operators, but I guess something like this: (Again I couldn't find any info on SO to answer my question.)

// friend function:
inline rain<T> operator*(const rain<T>& _rain, const T _t)
{
    return rain<T>(_rain.m_quantity_of_rain * _t);
}

inline rain<T> operator*(const T _t, const rain<T>& _rain)
{
    return rain<T>(_rain.m_quantity_of_rain * _t);
}

Again, I was unsure so thought its probably better to ask than learn it wrong. The 4 situations I was thinking of was the two above, and then the two hidden cases for when float may be converted to doublein the case whenTis typedouble`, and vice versa.

1

There are 1 answers

3
hidrargyro On

You could use directly double, and let the implicit converson do the task, but note that since float are smaller in size than double, this may cause a loss of data.

inline rain<T> operator*(const rain<T>& _rain, const double _t)
{
    return rain<T>(_rain.m_quantity_of_rain * _t);
}

inline rain<T> operator*(const double _t, const rain<T>& _rain)
{
    return rain<T>(_rain.m_quantity_of_rain * _t);
}

also with your attempt to avoid the specific template instantiation, like rain<int> you could throw a compilation error when somebody try to do that. Please refer here: How to intentionally cause a compile-time error on template instantiation