Is there a way to set an alias to specific form of a template?

Roderick Gibson kniteli at gmail.com
Sat Oct 8 03:52:25 PDT 2011


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?


More information about the Digitalmars-d-learn mailing list