Я пишу приложение для компьютерной графики, которое использует несколько различных библиотек, которые предоставляют многие необходимые функции.
Например, в колледже я написал кватернионные, оптимизированные 3-классные и оптимизированные матричные классы 4x4, которые мне нравятся, поскольку они эффективны, и я с ними хорошо знаком. Я также написал реализацию K-D Tree, которая зависит только от STL.
Наконец, я использую ITK для вычисления минимального собственного значения (и связанного собственного вектора) данной симметричной вещественной матрицы, среди прочего.
Со всеми этими библиотеками, содержащими свои собственные матрицы и векторные реализации, я обнаружил, что делаю много такого рода вещей:
FixedPointType closestPointCoords;
KdTree::HyperPoint target(3);
target[0] = transformedPoint[0];
target[1] = transformedPoint[1];
target[2] = transformedPoint[2];
KdTree::Neighbor result = FixedPointTree.FindNearestNeighbor(target);
minimumDistance = result.GetDistance();
closestPointCoords[0] = result.GetPoint().Get(0);
closestPointCoords[1] = result.GetPoint().Get(1);
closestPointCoords[2] = result.GetPoint().Get(2);
Очевидно, я мог бы написать функцию, которая выглядит примерно так:
FixedPointType ConvertHyperPointToFixedPointType(const KdTree::HyperPoint &p)
{
FixedPointType fixedPoint;
fixedPoint[0] = p[0];
fixedPoint[1] = p[1];
fixedPoint[2] = p[2];
return fixedPoint;
}
Я бы хотел избежать зависимости между библиотеками, выполнив что-то вроде этого:
class HyperPoint
{
...
operator FixedPointType()
{
// Same content as ConvertHyperPointToFixedPointType above
}
...
};
Но мне интересно, придумал ли кто-нибудь более изящное решение этой проблемы.
Возможно, мне следует взять страницу из книги .NET и создать статический класс Convert?
Как вы справились с избыточностью типов в библиотеках и с необходимостью частого преобразования между различными типами?
Подходит ли здесь шаблон Adapter ?
UPDATE
После еще нескольких исследований я наткнулся на TypeConverter . Так что эта проблема выглядит так, как будто она решена в C #. Я все еще ищу чистый, эффективный и простой способ сделать это в C ++. Пока что я думаю о канонических типах или, может быть, просто обнаженных функциях ConvertHyperPointToFixedPointType.
ОБНОВЛЕНИЕ 2
После еще большего прочтения звучит так, будто канонический тип фактически будет действовать как прокладка. Смотрите эту бумагу для получения дополнительной информации.
Вот пример кода, иллюстрирующий мою склонность:
class VectorConverter
{
public:
VectorConverter(const VectorImp1 &v1)
{
_data[0] = v1[0];
_data[1] = v1[1];
_data[2] = v1[2];
}
VectorConverter(const VectorImp2 &v2)
{
_data[0] = v2.Get(0);
_data[1] = v2.Get(1);
_data[2] = v2.Get(2);
}
operator VectorImp1()
{
return VectorImp1(_data[0], _data[1], _data[2]);
}
operator VectorImp2()
{
VectorImp2 v2;
v2.Set(0, _data[0]);
v2.Set(1, _data[1]);
v2.Set(2, _data[2]);
return v2;
}
// actual vector implementation goes here or a wrapper around an existing one
};
// example usage
VectorImp1 closestPointCoords, target;
// for the sake of illustration I included the cast, but you could implicitly cast
KdTree::Neighbor result = FixedPointTree.FindNearestNeighbor((VectorImp2)VectorConverter(target));
minimumDistance = result.GetDistance();
closestPointCoords = (VectorImp1)VectorConverter(result.GetPoint());
Спасибо за вашу помощь. Не стесняйтесь обновлять этот пост, если кто-то сталкивается с чем-то лучшим.