I have a Vector class which represents a 2D vector. It is templated to allow any numerical type to be used for the x and y components. As an example, one of the arithmetic operators I overload is * for multiplying a vector with a scalar:
template <typename T, typename U>
inline const Vector<T> operator*(const Vector<T>& vector, U scalar) {
return Vector<T>(vector.x * scalar, vector.y * scalar);
}
(I also have a function with the parameters in the opposite order to allow scalar * Vector in addition to Vector * scalar).
As you can see, I use <T, U> instead of simply <T> so that the scalar doesn’t have to be the same type as the Vector. When I didn’t do this, surprisingly Vector<double> * int wouldn’t compile (I thought the int would automatically widen).
In any case, I don’t simply want to return a Vector<T>. I want to mimic the built-in types and return whichever has higher precision, T or U. So for example, Vector<int> * double => Vector<double> while Vector<double> * short => Vector<double>.
Is this possible?
There are two solutions to this. In Pre C++11 you can write a template like:
etc. and write a lot of specialisations, then you can use that to look up the return type, e.g.:
Alternatively C++11 makes this straightforward, you can write
autofor the return type and use->to specify the return type after the rest of the function:Which allows you to use
decltypefor the return type of a function, setting it based on what would happen for promotion naturally withvector.x * scalar.