Thread overview
Array/collection of templated class
Apr 20, 2006
Derek Parnell
Apr 20, 2006
Hasan Aljudy
Apr 20, 2006
BCS
April 20, 2006
I'm working on a project of mine, and I came across this little problem.  Now, it may well be that the solution is staring me in the face, but I just can't seem to come up with a feasible solution to this: I can't have an array of a templated class.

To illustrate:

########## foo.d
# class Foo (T) {
#   public this (T a_value) { p_value = a_value; }
#
#   public T value () { return p_value; }
#   private T p_value;
# }
#
# void main () {
#   Foo[] arr;
# }

This will give the error:
foo.d(9): class foo.Foo(T) is used as a type

Now, granted, I expected this.  But I'm at a loss as to what to do.  Sure, if I had a way of knowing the signatures of the template instances I could just use "Object[]" decleration and a cast() expression on the lookup, but this is for a system where I usually won't know.

Ideas?

-- Chris Nicholson-Sauls
April 20, 2006
On Thu, 20 Apr 2006 02:24:17 -0500, Chris Nicholson-Sauls wrote:

> I'm working on a project of mine, and I came across this little problem.  Now, it may well be that the solution is staring me in the face, but I just can't seem to come up with a feasible solution to this: I can't have an array of a templated class.
> 
> To illustrate:
> 
> ########## foo.d
> # class Foo (T) {
> #   public this (T a_value) { p_value = a_value; }
> #
> #   public T value () { return p_value; }
> #   private T p_value;
> # }
> #
> # void main () {
> #   Foo[] arr;
> # }
> 
> This will give the error:
> foo.d(9): class foo.Foo(T) is used as a type
> 
> Now, granted, I expected this.  But I'm at a loss as to what to do.  Sure, if I had a way of knowing the signatures of the template instances I could just use "Object[]" decleration and a cast() expression on the lookup, but this is for a system where I usually won't know.
> 
> Ideas?

Does this help ... ?

// ----------------------------
import std.stdio;
import std.boxer;

class Foo (T) {
   public this (T a_value) { p_value = a_value; }

   public T value () { return p_value; }
   private T p_value;
 }


void main ()
{
   Box[] arr;

   arr ~= box(new Foo!(int)(1));
   arr ~= box(new Foo!(real)(2.345));
   arr ~= box(new Foo!(char[])("test"));

   foreach(int i, Box b; arr)
   {
       if (unboxable!(Foo!(int))(b) )
           writefln("%2d  int: %s", i, (unbox!(Foo!(int))(b)).value);
       else if (unboxable!(Foo!(real))(b) )
           writefln("%2d real: %s", i, (unbox!(Foo!(real))(b)).value);
       else if (unboxable!(Foo!(char[]))(b) )
           writefln("%2d char[]: %s", i, (unbox!(Foo!(char[]))(b)).value);
   }
}
// ----------------------------

Remember to compile with '-release' because of the 'std.boxer' issue in Phobos.

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocracy!"
20/04/2006 5:51:52 PM
April 20, 2006
Chris Nicholson-Sauls wrote:
> I'm working on a project of mine, and I came across this little problem.  Now, it may well be that the solution is staring me in the face, but I just can't seem to come up with a feasible solution to this: I can't have an array of a templated class.
> 
> To illustrate:
> 
> ########## foo.d
> # class Foo (T) {
> #   public this (T a_value) { p_value = a_value; }
> #
> #   public T value () { return p_value; }
> #   private T p_value;
> # }
> #
> # void main () {
> #   Foo[] arr;
> # }
> 
> This will give the error:
> foo.d(9): class foo.Foo(T) is used as a type
> 
> Now, granted, I expected this.  But I'm at a loss as to what to do.  Sure, if I had a way of knowing the signatures of the template instances I could just use "Object[]" decleration and a cast() expression on the lookup, but this is for a system where I usually won't know.
> 
> Ideas?
> 
> -- Chris Nicholson-Sauls

Hmm .. templates are generally used for things that you know at compile time, if you don't, well .. trying doing something different.
April 20, 2006
Might this work?

abstract class Foo
{
	abstract TypeInfo TypeOf();
}

class FooT (T) : Foo
{
	public this (T a_value) { p_value = a_value; }

	public T value () { return p_value; }

	TypeInfo TypeOf() { return typeid(T); }

	private T p_value;
}

void main ()
{
	Foo[] arr = new Foo[3];

	arr[0] = new FooT!(int)(123);
	arr[1] = new FooT!(char[])("hello world");
	arr[2] = new FooT!(Object)(arr[0]);
}


Chris Nicholson-Sauls wrote:
> I'm working on a project of mine, and I came across this little problem.  Now, it may well be that the solution is staring me in the face, but I just can't seem to come up with a feasible solution to this: I can't have an array of a templated class.
> 
> To illustrate:
> 
> ########## foo.d
> # class Foo (T) {
> #   public this (T a_value) { p_value = a_value; }
> #
> #   public T value () { return p_value; }
> #   private T p_value;
> # }
> #
> # void main () {
> #   Foo[] arr;
> # }
> 
> This will give the error:
> foo.d(9): class foo.Foo(T) is used as a type
> 
> Now, granted, I expected this.  But I'm at a loss as to what to do.  Sure, if I had a way of knowing the signatures of the template instances I could just use "Object[]" decleration and a cast() expression on the lookup, but this is for a system where I usually won't know.
> 
> Ideas?
> 
> -- Chris Nicholson-Sauls
April 20, 2006
Hasan Aljudy wrote:
> Chris Nicholson-Sauls wrote:
> 
>> I'm working on a project of mine, and I came across this little problem.  Now, it may well be that the solution is staring me in the face, but I just can't seem to come up with a feasible solution to this: I can't have an array of a templated class.
>>
>> To illustrate:
>>
>> ########## foo.d
>> # class Foo (T) {
>> #   public this (T a_value) { p_value = a_value; }
>> #
>> #   public T value () { return p_value; }
>> #   private T p_value;
>> # }
>> #
>> # void main () {
>> #   Foo[] arr;
>> # }
>>
>> This will give the error:
>> foo.d(9): class foo.Foo(T) is used as a type
>>
>> Now, granted, I expected this.  But I'm at a loss as to what to do.  Sure, if I had a way of knowing the signatures of the template instances I could just use "Object[]" decleration and a cast() expression on the lookup, but this is for a system where I usually won't know.
>>
>> Ideas?
>>
>> -- Chris Nicholson-Sauls
> 
> 
> Hmm .. templates are generally used for things that you know at compile time, if you don't, well .. trying doing something different.

The reason I won't know, is because the template instances are built and made available by various objects, independantly of each other.  Consider this contrived example:

########## module somelib.d
# class Foo (T) {
#   public this (char[] a_name, T* a_what) {
#     p_name = a_name ;
#     p_what = a_what ;
#   }
#
#   public char[] name  () { return p_name  ; }
#   public T      value () { return *p_what ; }
#
#   private char[] p_name;
#   private T*     p_what;
# }
#
# class Bar {
#   package int p_alpha ,
#               p_beta  ;
#
#   public Foo[] wrap () {
#     Foo[] result;
#     result ~= new Foo!(int)(
#   }
#
#   public int doStuff () { /* ... */ }
# }

########## module someapp.d
# import std.stdio ;
# import somelib   ;
#
# void main () {
#   Bar   mybar = new Bar    ;
#   Foo[] wbar  = mybar.wrap ;
#
#   while (mybar.doStuff)
#     foreach (x; wbar)
#       writefln("%s(%s)", x.name, x.value);
# }

-- Chris Nicholson-Sauls
April 20, 2006
Derek Parnell wrote:
> On Thu, 20 Apr 2006 02:24:17 -0500, Chris Nicholson-Sauls wrote:
> 
> 
>>I'm working on a project of mine, and I came across this little problem.  Now, it may well be that the solution is staring me in the face, but I just can't seem to come up with a feasible solution to this: I can't have an array of a templated class.
>>
>>To illustrate:
>>
>>########## foo.d
>># class Foo (T) {
>>#   public this (T a_value) { p_value = a_value; }
>>#
>>#   public T value () { return p_value; }
>>#   private T p_value;
>># }
>>#
>># void main () {
>>#   Foo[] arr;
>># }
>>
>>This will give the error:
>>foo.d(9): class foo.Foo(T) is used as a type
>>
>>Now, granted, I expected this.  But I'm at a loss as to what to do.  Sure, if I had a way of knowing the signatures of the template instances I could just use "Object[]" decleration and a cast() expression on the lookup, but this is for a system where I usually won't know.
>>
>>Ideas?
> 
> 
> Does this help ... ?
> 
> // ----------------------------
> import std.stdio;
> import std.boxer;
> 
> class Foo (T) {
>    public this (T a_value) { p_value = a_value; }
> 
>    public T value () { return p_value; }
>    private T p_value;
>  }
> 
> 
> void main ()
> {
>    Box[] arr;
> 
>    arr ~= box(new Foo!(int)(1));
>    arr ~= box(new Foo!(real)(2.345));
>    arr ~= box(new Foo!(char[])("test"));
> 
>    foreach(int i, Box b; arr)
>    {
>        if (unboxable!(Foo!(int))(b) )
>            writefln("%2d  int: %s", i, (unbox!(Foo!(int))(b)).value);
>        else if (unboxable!(Foo!(real))(b) )
>            writefln("%2d real: %s", i, (unbox!(Foo!(real))(b)).value);
>        else if (unboxable!(Foo!(char[]))(b) )
>            writefln("%2d char[]: %s", i, (unbox!(Foo!(char[]))(b)).value);
>    }
> }
> // ----------------------------
> 
> Remember to compile with '-release' because of the 'std.boxer' issue in
> Phobos.
> 

Sure, std.boxer will make the array work, but I would still have to be able to get the signature in order to unbox it.  This is a system with arbitrary templates.  It works for me in other cases; but now I'm wanting to provide an enumeration (the other method is to retrieve by name).

Plus the whole '-release' thing is a little annoying.  ;)  I hope Walter comes up with a genius solution for that soon.

-- Chris Nicholson-Sauls
April 20, 2006
This actually does /almost/ work, except that I can't use the TypeInfo object to redescribe the template instance.  There almost needs to be some kind of covariance across template instances.

-- Chris Nicholson-Sauls

BCS wrote:
> Might this work?
> 
> abstract class Foo
> {
>     abstract TypeInfo TypeOf();
> }
> 
> class FooT (T) : Foo
> {
>     public this (T a_value) { p_value = a_value; }
> 
>     public T value () { return p_value; }
> 
>     TypeInfo TypeOf() { return typeid(T); }
> 
>     private T p_value;
> }
> 
> void main ()
> {
>     Foo[] arr = new Foo[3];
> 
>     arr[0] = new FooT!(int)(123);
>     arr[1] = new FooT!(char[])("hello world");
>     arr[2] = new FooT!(Object)(arr[0]);
> }
> 
> 
> Chris Nicholson-Sauls wrote:
> 
>> I'm working on a project of mine, and I came across this little problem.  Now, it may well be that the solution is staring me in the face, but I just can't seem to come up with a feasible solution to this: I can't have an array of a templated class.
>>
>> To illustrate:
>>
>> ########## foo.d
>> # class Foo (T) {
>> #   public this (T a_value) { p_value = a_value; }
>> #
>> #   public T value () { return p_value; }
>> #   private T p_value;
>> # }
>> #
>> # void main () {
>> #   Foo[] arr;
>> # }
>>
>> This will give the error:
>> foo.d(9): class foo.Foo(T) is used as a type
>>
>> Now, granted, I expected this.  But I'm at a loss as to what to do.  Sure, if I had a way of knowing the signatures of the template instances I could just use "Object[]" decleration and a cast() expression on the lookup, but this is for a system where I usually won't know.
>>
>> Ideas?
>>
>> -- Chris Nicholson-Sauls