C ++模板 - 成员函数的部分特化

时间:2012-12-31 04:53:43

标签: c++ class templates inheritance specialization

我正在尝试根据模板参数指定的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功能。

任何提示都非常赞赏!

2 个答案:

答案 0 :(得分:7)

我会建议这个解决方案:

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<>来演示一个看起来很有用的功能。

答案 1 :(得分:5)

以下是您的示例的工作原理。您首先声明主要模板:

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;
    }
};