Я пытаюсь специализировать некоторые геометрические функции в зависимости от 2D или 3D, заданные параметром шаблона. Лучше всего, если я включу (очень сломанный) код для игрушечной версии проблемы:
template <typename T, int d>
class Point
{
public:
int x;
int y;
int z;
T add ()
{
return T(0);
}
template <>
T add <T, 2> ()
{
return x + y;
}
template <>
T add <T, 3> ()
{
return x + y + z;
}
};
Этот код с треском не скомпилируется. Я перепробовал множество различных комбинаций форматов параметров шаблонов и определений классов, и не могу найти способ специализировать функции на «d», оставляя «T» в общем.
В моем реальном решении я пытаюсь вычислить такие вещи, как градиенты, кривизна, интерполяция и т. Д., Специально для 2D или 3D случаев. Некоторые вещи, такие как вычисления градиента, могут просто использовать параметр ‘d’ для ограничения итераций цикла for. Другие, такие как интерполяция, требуют отдельной функции для 2D и 3D.
Любые намеки очень ценятся!
Вот как ваш пример может работать. Сначала вы объявляете свой основной шаблон:
template <typename T, int d> class Point;
Нет необходимости определять его, потому что у вас нет общей реализации.
Затем вы создаете частичные специализации для разного числа измерений, но ваши частичные специализации по-прежнему будут иметь тип T в качестве параметра шаблона:
template <typename T>
class Point<T,2>
{
public:
T x;
T y;
T add()
{
return x + y;
}
};
template <typename T>
class Point<T,3>
{
public:
T x;
T y;
T z;
T add()
{
return x + y + z;
}
};
Я бы предложил это решение:
template <typename T, int d>
class Point : public Point<T, d-1>
{
typedef Point<T, d-1> base;
T m_value;
public:
T add()
{
return m_value + base::add();
}
//another method which returns you the point value
template<int N>
T get()
{
return N==d ? m_value : base::get<N>();
}
};
template <typename T>
class Point<T,0>
{
protected:
T add()
{
return T(); //default value which is zero for all builtin types
}
template<int N>
T get() { return T(); }
};
Используя это решение, вы можете получить столько очков, сколько захотите, но больше, чем zero
,
Point<int,1> p1; //contains 1 point
Point<int,2> p2; //contains 2 points
Point<int,3> p3; //contains 3 points
Point<int,4> p4; //contains 4 points
Point<int,5> p5; //contains 5 points
auto x1 = p5.get<1>(); //get first point
auto x3 = p5.get<3>(); //get third point
auto x4 = p5.get<4>(); //get fourth point
Или используйте эти typedef для удобства:
typedef Point<int,2> Point2D;
typedef Point<int,3> Point3D;
//then use them
Point2D p2d;
Point3D p3d;
Ну, это просто базовая идея, которая может быть улучшена, поддерживая множество полезных функций. Я просто написал get<>
продемонстрировать одну функциональность, которая кажется полезной.