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