Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template specialization alias

I have a problem I came up with recently. I actually think it can not be solved as I would like it to be, but it would be quite handy if it could. Anyway, here's the problem:

I will give you an example I've seen a few days ago on this forum since it will be easier to explain with it. Let's say I'm trying to create a Tensor struct, this way:

template <int N>
struct Tensor
{
    Tensor<N - 1> x;
    Tensor<N - 1> y;
    Tensor<N - 1> z;
};

To avoid infinite recursion, I would have to write the template specialization for N = 1.

template<>
struct Tensor<1>
{
    double x;
    double y;
    double z;
};

Actually, when N = 1, this Tensor is actually a Vector (physical one). Let's say I already have a Vector struct defined this way:

struct Vector
{
    double x;
    double y;
    double z;
};

This struct is exactly like Tensor<1>. Since the Vector struct already existed and, let's say I did not implemented it myself, I would like to be able to make the Tensor<1> struct an alias of the Vector struct. Just like a typedef. So, I would like to do it this way:

// C++03
typedef Vector Tensor<1>;

// or C++11
using Tensor<1> = Vector;

This way, Tensor<1> and Vector would be the exact same struct, so it would I could use one instead of another in the program wherever I want and I would not have to write the same struct twice.

However, it's actually impossible to define a template specialization that way. If it was, I would not be asking the question there.

Note: I know the previous example is not a good one since we can still do this:

using Vector = Tensor<1>;

But it is quite bothersome if I want to do it with specializations of two different structs. For example when writing a geometry library that could compute geometry in N-dimensional spaces:

using Circle<2> = Hypersphere<2>;

So, to sum up: is there a way to create template specializations by defining it as the alias of another one?

like image 555
Morwenn Avatar asked May 03 '12 20:05

Morwenn


1 Answers

Given legacy classes Scalar, Vector and Matrix, you could use inheritance:

template<>
class Tensor<0>: public Scalar {};

template<>
class Tensor<1>: public Vector {};

template<>
class Tensor<2>: public Matrix {};

Note that this is not abuse of inheritance because you are modelling an is-a relationship.

like image 94
TemplateRex Avatar answered Nov 08 '22 16:11

TemplateRex