1.
При частичной специализации шаблона следует указывать только те параметры шаблона, которые фактически являются параметрами.Поскольку вы уже установили dim
как 2 или 3, нет необходимости указывать его снова.
template<typename T>
class Vector<2, T>
{
....
2.
Специализация класса действительно означает изменение всей декларации.Следовательно, члены универсального Vector<dim, T>
не будут доступны в специализированном Vector<2, T>
.Вы можете сделать обобщенный Vector<dim, T>
как внутренний базовый класс и создать подкласс только для специализации:
template<int dim, typename T>
class VectorImpl;
...
template<int dim, typename T = float>
class Vector : public VectorImpl<dim, T> {};
template<typename T>
class Vector<2, T> : public VectorImpl<2, T>
{
public:
T x() const { ... }
};
3.
Вам не нужно определять VecType
!Внутри шаблона вы можете просто использовать Vector
.Он будет автоматически выведен для ссылки на класс с правильными параметрами.
Конечный результат, который компилируется:
#include <array>
template<int dim, typename T>
class VectorImpl
{
public:
//typedef Vector<dim, T> VecType;
VectorImpl() { }
VectorImpl(const VectorImpl& other) { }
VectorImpl& operator=(const VectorImpl& other) { return *this; }
VectorImpl operator+(const VectorImpl& other) { return *this; }
VectorImpl operator-(const VectorImpl& other) { return *this; }
T operator*(const VectorImpl& other) { return 0; }
protected:
std::array<T, dim> elements;
};
template <int dim, typename T = float>
class Vector : public VectorImpl<dim, T> {};
template<typename T>
class Vector<2, T> : public VectorImpl<2, T>
{
public:
T x() const { return this->elements[0]; }
T y() const { return this->elements[1]; }
};
template<typename T>
class Vector<3, T> : public VectorImpl<2, T>
{
public:
T x() const { return this->elements[0]; }
T y() const { return this->elements[1]; }
T z() const { return this->elements[2]; }
};
int main()
{
Vector<2> v;
Vector<3> vv;
v + v;
vv.z();
}