I'm writing a simple maths library with a template vector type:
template<typename T, size_t N>
class Vector {
public:
Vector<T, N> &operator+=(Vector<T, N> const &other);
// ... more operators, functions ...
};
Now I want some additional functionality specifically for some of these. Let's say I want functions x()
and y()
on Vector<T, 2>
to access particular coordinates. I could create a partial specialization for this:
template<typename T>
class Vector<T, 3> {
public:
Vector<T, 3> &operator+=(Vector<T, 3> const &other);
// ... and again all the operators and functions ...
T x() const;
T y() const;
};
But now I'm repeating everything that already existed in the generic template.
I could also use inheritance. Renaming the generic template to VectorBase
, I could do this:
template<typename T, size_t N>
class Vector : public VectorBase<T, N> {
};
template<typename T>
class Vector<T, 3> : public VectorBase<T, 3> {
public:
T x() const;
T y() const;
};
However, now the problem is that all operators are defined on VectorBase
, so they return VectorBase
instances. These cannot be assigned to Vector
variables:
Vector<float, 3> v;
Vector<float, 3> w;
w = 5 * v; // error: no conversion from VectorBase<float, 3> to Vector<float, 3>
I could give Vector
an implicit conversion constructor to make this possible:
template<typename T, size_t N>
class Vector : public VectorBase<T, N> {
public:
Vector(VectorBase<T, N> const &other);
};
However, now I'm converting from Vector
to VectorBase
and back again. Even though the types are the same in memory, and the compiler might optimize all this away, it feels clunky and I don't really like to have potential run-time overhead for what is essentially a compile-time problem.
Is there any other way to solve this?
See Question&Answers more detail:os