И чем это лучше? Всё равно придётся копипастить весь класс..
Нет, только конструкторы с аргументами, остальное унаследуется. Хотя стоит ли оно того - хз. Напр вот реализация
C++ (Qt)
float Triangle::Area( void )
{
return QVector3D::crossProduct(vertices[1] - vertices[0], vertices[2] - vertices[1]).length() / 2;
}
Очевидно для arma::vec3 это не прокатит. Арифметика (-, /) там наверное есть, а вот статический crossProduct вряд ли, да и length может быть другим. То же самое случится со многими (если не всеми) содержательными методами, итог обобщения - неск косметических сеттеров.
Также template проблематичен и с др стороны. Допустим мы добились желаемого и теперь может свободно объявлять
C++ (Qt)
QVector<Triangle<QVector3D> > vec1;
QVector<Triangle<arma::vec3> > vec2;
...
Ну и как теперь с этим работать? Напр был класс
C++ (Qt)
struct Model {
..
QVector<Triangle> mPoly;
..
};
А теперь, когда Triangle стал шаблоном - какой контейнер писать? И к кому обращаться методам использующим mPoly? Утрированный пример:
C++ (Qt)
QImage<ARGB_32>;
QImage<RGB_32>;
QImage<Monochrome>;
...
Минусы (или просто глупость) такого решения очевидны.
Мои предложения
1) Реализовать всю содержательную часть Triangle для "старшего" типа, здесь это arma::vec3 и только хранилище (vertices) имеет тип аргумента template
C++ (Qt)
class Triangle {
Triangle( arma::vec3 & a, arma::vec3 & b, arma::vec3 & c )
{
SetVer(0, a);
SetVer(1, b);
SetVer(2, c);
}
// Содержательные методы
//
virtual arama::vec3 GetVer( size_t index ) = 0;
virtual void SetVer( size_t index, const arama::vec3 & val ) = 0;
};
template <class T>
class TriangleImpl : public Triangle {
virtual arama::vec3 GetVer( size_t index ) { return vertices[index]; };
virtual void SetVer( size_t index, const arama::vec3 & val ) { vertices[index] = val; }
T vertices[3];
};
Теперь T может быть чем угодно - лишь бы он умел приводиться к arma::vec3, это легко обеспечить. Да, есть расходы на перегонку, но они терпимы.
2) Подобным образом "замкнуть" template внутри контейнера полигонов
C++ (Qt)
struct CPolyList {
virtual Triangle & Get( size_t index );
};
template <class T>
struct CPolyListImp : public CPolyList {
virtual Triangle & Get( size_t index ) { return mData[index]; }
QVector<TroangleImpl<T> > mData;
};
Теперь мы можем писать
C++ (Qt)
CPolyList * poly;
poly = new CPolyListImp<QVector3D>;
..
poly = new CPolyListImp<arma::vec3>;
3) Вот что-то мне никак не верится что есть необходимость в хранении фундаментальных данных (полигонов) 2-мя или более способами. Впечатление что площадь считается по формуле Герона - ну тогда да, точность низкая.