Я пишу простую математическую библиотеку с шаблоном векторного типа:
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
и обратно. Несмотря на то, что типы в памяти одинаковы, и компилятор может оптимизировать все это, это кажется неуклюжим, и я не очень хочу иметь потенциальные накладные расходы во время выполнения, что по существу является проблемой времени компиляции.
Есть ли другой способ решить эту проблему?