Я пишу простую математическую библиотеку с типом вектора шаблона:
template<typename T, size_t N>
class Vector {
public:
Vector<T, N> &operator+=(Vector<T, N> const &other);
// ... more operators, functions ...
};
Теперь я хочу, чтобы некоторые некоторые функции были специально для некоторых из них. Предположим, что мне нужны функции x()
и y()
на Vector<T, 2>
для доступа к определенным координатам. Я мог бы создать частичную специализацию для этого:
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;
};
Но теперь я повторяю все, что уже существует в общем шаблоне.
Я мог бы также использовать наследование. Переименовав шаблон шаблона на VectorBase
, я мог бы сделать это:
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;
};
Однако теперь проблема в том, что все операторы определены на VectorBase
, поэтому они возвращают экземпляры VectorBase
. Они не могут быть назначены переменным Vector
:
Vector<float, 3> v;
Vector<float, 3> w;
w = 5 * v; // error: no conversion from VectorBase<float, 3> to Vector<float, 3>
Я мог бы дать Vector
неявный конструктор преобразования, чтобы сделать это возможным:
template<typename T, size_t N>
class Vector : public VectorBase<T, N> {
public:
Vector(VectorBase<T, N> const &other);
};
Однако теперь я перехожу от Vector
в VectorBase
и обратно. Несмотря на то, что типы одинаковы в памяти, и компилятор может оптимизировать все это, он чувствует себя неуклюжим, и мне не очень нравится иметь потенциальные накладные расходы во время выполнения, что по существу является проблемой времени компиляции.
Есть ли другой способ решить эту проблему?