C++ templates - partial specialisation of member function

I am trying to specialise some geometrical functions depending on 2D or 3D, specified by a template parameter. Best if I include some (very broken) code for a toy version of the problem:

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

This code fails miserably to compile. I've tried lots of different combinations of template parameter formats and class definitions, and cannot find a way to do function specialisation on 'd' whilst leaving the 'T' general.

In my actual solution I'm trying to calculate things like gradients, curvature, interpolation, etc, specialised for 2D or 3D cases. Some things, like gradient calculations, can simply use the 'd' parameter to limit for-loop iterations. Others, like interpolation, require a separate function for 2D and 3D.

Any hints much appreciated!

Answers


Here is how your example might work. You first declare your primary template:

template <typename T, int d> class Point;

There is no need to define it, because you don't have a general implementation.

Next, you create partial specializations for different numbers of dimensions, but your partial specializations will still have type T as a template parameter:

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

I would suggest this solution:

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

};

Using this solution you can have as many points as you want, but greater than 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

Or have these typedefs for convenience:

typedef Point<int,2> Point2D;
typedef Point<int,3> Point3D;

//then use them
Point2D p2d;
Point3D p3d;

Well that is just a basic idea which can be further enhanced, supporting many useful functionalities. I just wrote get<> to demonstrate one functionality which seems to be useful.


Need Your Help

IOS & objective C development - how to make the login page appear to the user?

ios objective-c iphone xcode6

I am in my first days of IOS app development, I am trying to build an authentication system for an already existent iOS App using Objective C.

Converting a object list (from DB) to a sitemapdatasource

c# asp.net treeview hierarchy

I am working with a Folder list object, that has a list of folder obj's with a name, ID, and parentID. I am trying to fill out a asp:TreeView control but the datasource of a List&lt;&gt; is not th...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.