www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Array/collection of templated class

reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
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
Apr 20 2006
next sibling parent reply Derek Parnell <derek psych.ward> writes:
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
Apr 20 2006
parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
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
Apr 20 2006
prev sibling next sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
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.
Apr 20 2006
parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
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
Apr 20 2006
prev sibling parent reply BCS <BCS_member pathlink.com> writes:
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

Apr 20 2006
parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
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


Apr 20 2006