Passing a generic struct as parameter

Jonathan M Davis jmdavisProg at gmx.com
Thu Jun 30 17:12:43 PDT 2011


On 2011-06-30 16:39, Zardoz wrote:
> I have a parametrized struct (Vector!(T, dim)) that takes two parameters
> (Type and a number). And made some Alias with defaults parameters.
> 
> In other struct (Matrix!(T, dim)), that uses these struct to represent a
> matrix in column-major order. I have a internall alias for Vector using
> internally (alias Vector!(T,dim_) VCol;) . The problem that I have it's
> when I try to use opIndexAssign to assign to a column a Vector. I try
> this :
> 
> void opIndexAssign(Vector v, size_t j) {
> if ( code that see if VCol if same type that v ) {
> col[j] = v;
> } else {
> col[j] = cast (VCol) v;
> }
> }
> 
> But not compile... I get this error :
> Error: struct zmath.vector.Vector(T,ulong dim_) if (__traits
> (isFloating,T)) is used as a type
> Error: template instance zmath.matrix.Matrix!(float,2) error instantiating
> 
> So finally I try this :
> /**
> * Assigns a new column vector
> */
> void opIndexAssign(VCol v, size_t j) {
> col[j] = v;
> }
> 
> But now I must do cast outside, even knowing that are same type. Plus now
> I must keep VCol alias public.
> 
> How should fix this, or What is the correct way of doing this ?
> 
> 
> Note : I have a opCast for Vector that cast between Vectors with
> different parameters and it's checked that works.
> 
> Second Question : I'm thinking publish this small Vector/Quaternion/
> Matrix lib that I made learning D2.. where I should put and how ? (and I
> use Git)

The first thing that you need to understand is that Vector is not a type. It 
does not exist. Vector!(int, 4) is a type. Vector!(float, 3) is a type. Vector 
is not. Vector is a template for a type. When you use a template, you 
instantiate it for a particular set of arguments, and that creates a new type. 
An instantiation of a templated type such as Vector is a type, and every 
instantiation is its own, separate type which has no connection with any other 
instantion of that template. So, it makes no sense for a function to take a 
Vector (though within the Vector template that works, because Vector stands 
for that particular instantiation inside of the Vector template). If you want 
a function to take multiple instantiations of a template, then you need to 
templatize the function. If you want it to take a particular instantiation of 
a template, then you give its parameter that exact template instantiation.

Now, if you want two separate instantions (such as Vector!(int, 3) and Vector!
(float, 3)) to interact, you're going to need to either write opCasts to cast 
between them or have templated functions which are templated on both of their 
types (e.g. func(V1, V2)(V1 vector1, V2 vector2) {...}). They are two 
completed different types, just like if you created IntVector and FloatVector, 
so you have to write code which allows them to interact. They aren't going to 
just work together because they came from the same template.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list