On 10/7/2011 11:35 PM, Ali Çehreli wrote:
On Fri, 07 Oct 2011 18:29:26 -0700, Roderick Gibson wrote:

This may be the completely wrong approach, but I am basically thinking
of something like this (I am aware this will not compile, it's
psuedocode):

class Vector(T) {
        ... //definition here
}

alias Vector(float, float) vec2f;
auto v = new vec2f(1.0,1.0);

I am making a templated Vector class (a mathematical vector) that will
have varying types (thus a template) and dimensions (via variadic
functions), so that the same template definition will work for 2d or 3d
vectors (or 4d, etc).

I then want the programmer to be able to define
the specific forms that he wants so he can easily keep track of them
(without getting confused about which is a 2d integer vector and which
is a 3d float vector), and then use those forms in a type safe manner.
Is this even possible? If it is, but it's the wrong way to do it, what's
the right way?

Basically I wanted to write it once and not worry about writing it again
to handle different types and dimensions (no vec2i class, or vec2f, or
vec3f, or vec3i, etc). Templates easily handles the type requirement,
but what about the dimensional requirement? Am I just going to have to
rewrite it when I add dimensions?

You can take advantage of 'Template Value Parameters' and 'Typesafe
Variadic Functions':

   http://www.d-programming-language.org/
template.html#TemplateValueParameter

   http://www.d-programming-language.org/function.html

class Vector(T, int N)
{
     T[N] elements;

     this(T[] elements ...)
     {
         this.elements = elements;
     }
}

alias Vector!(double, 2) Vec2D;
alias Vector!(double, 3) Vec3D;

void main()
{
     auto v2d = new Vec2D(2.2, 2.2);
     auto v3d = new Vec3D(3.3, 3.3, 3.3);

     // Alternatively, all parameters at once:
     auto v3d_too = new Vec3D([ 33, 33, 33, ]);
}

(Some would find 'size_t N' to be more appropriate since N is a
dimension.)

Ali

I decided this would be the best way, thank you. One question though, I noticed with this method that you can only assert that the dimension and the parameter list length match at runtime (ie, someone could instantiate a vec2d as vec2d(2.2, 2.2, 3.1) and the compiler will happily accept it), I'm guessing constraints are what's needed, but I don't know how to get the parameter count at compile time, only at runtime (via elements.length). The compiler *should* know the length at compile time shouldn't it?

I managed to get it to at least stop the compilation with

this(T[N] elements...)

but the error messages are terrible. Is there a better way, perhaps using a static assert?

Reply via email to