www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to chain constructor args to a template memeber

reply BCS <none anon.com> writes:
Using D2, I have a template class that looks something like this:

class C(T) { T t; }

(For simplicity, assume T is required to be a struct of some kind.) I want 
to have a constructor that passes on some of it's args to a constructor for 
t. This is easy as long as I don't need it to work for arbitrary constructors.

What I want to do (that doesn't seem to work) is this:

this(Args...)(int foo, float bar, Args args)
{
   t = T(args);

   ...
}

Any ideas on fixes or work arounds?

-- 
... <IXOYE><
Mar 10 2010
next sibling parent Jacob Carlborg <doob me.com> writes:
On 3/11/10 08:58, BCS wrote:
 Using D2, I have a template class that looks something like this:

 class C(T) { T t; }

 (For simplicity, assume T is required to be a struct of some kind.) I
 want to have a constructor that passes on some of it's args to a
 constructor for t. This is easy as long as I don't need it to work for
 arbitrary constructors.

 What I want to do (that doesn't seem to work) is this:

 this(Args...)(int foo, float bar, Args args)
 {
 t = T(args);

 ...
 }

 Any ideas on fixes or work arounds?
D doesn't seem support constructor templates in classes.
Mar 11 2010
prev sibling next sibling parent reply Lutger <lutger.blijdestijn gmail.com> writes:
BCS wrote:

 Using D2, I have a template class that looks something like this:
 
 class C(T) { T t; }
 
 (For simplicity, assume T is required to be a struct of some kind.) I want
 to have a constructor that passes on some of it's args to a constructor for
 t. This is easy as long as I don't need it to work for arbitrary
 constructors.
 
 What I want to do (that doesn't seem to work) is this:
 
 this(Args...)(int foo, float bar, Args args)
 {
    t = T(args);
 
    ...
 }
 
 Any ideas on fixes or work arounds?
 
Workaround if T has a single constructor, perhaps it can be generalized with some work: this(int foo, float bar, std.traits.ParameterTypeTuple!(T.__ctor) args) { t = T(args); }
Mar 11 2010
parent BCS <none anon.com> writes:
Hello Lutger,

 Workaround if T has a single constructor, perhaps it can be
 generalized with some work:
 
 this(int foo, float bar, std.traits.ParameterTypeTuple!(T.__ctor)
 args)
 {
 t = T(args);
 }
Not exactly ideal, but... :) -- ... <IXOYE><
Mar 11 2010
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 11 Mar 2010 02:58:52 -0500, BCS <none anon.com> wrote:

 Using D2, I have a template class that looks something like this:

 class C(T) { T t; }

 (For simplicity, assume T is required to be a struct of some kind.) I  
 want to have a constructor that passes on some of it's args to a  
 constructor for t. This is easy as long as I don't need it to work for  
 arbitrary constructors.

 What I want to do (that doesn't seem to work) is this:

 this(Args...)(int foo, float bar, Args args)
 {
    t = T(args);

    ...
 }

 Any ideas on fixes or work arounds?
What about a static function instead of a constructor? i.e. static C create(Args...)(int foo, float bar, Args args) { auto c = new C(foo, bar); c.t = T(args); return c; } It's a shame template constructors aren't allowed, they aren't even virtual functions! -Steve
Mar 11 2010
parent reply BCS <none anon.com> writes:
Hello Steven,

 What about a static function instead of a constructor?
 
 i.e.
 
 static C create(Args...)(int foo, float bar, Args args)
 {
 auto c = new C(foo, bar);
 c.t = T(args);
 return c;
 }
That's my fallback position.
 It's a shame template constructors aren't allowed, they aren't even
 virtual functions!
Ditto. -- ... <IXOYE><
Mar 11 2010
parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Thu, Mar 11, 2010 at 21:03, BCS <none anon.com> wrote:

 i.e.

 static C create(Args...)(int foo, float bar, Args args)
 {
 auto c = new C(foo, bar);
 c.t = T(args);
 return c;
 }
What about a static function instead of a constructor?
Two variations on the same theme: storing (Args...) as a template parameter in the host class class Host(Hosted, Args...) { Hosted t; this(int foo, float bar, Args args) { t = Hosted(args); } } and using a helper function to do the type extraction: Host!(Hosted, Args) host(Hosted, Args...)(int foo, float bar, Args args) { return new Host!(Hosted, Args)(foo, bar, args); } Or, give the host a constructor taking a Hosted already created: class Host2(Hosted) { Hosted h; this(int foo, float bar, Hosted h) { this.h = h; } } Host2!(Hosted) host2(Hosted, Args...)(int foo, float bar, Args args) { auto h = Hosted(args); return new Host2!(Hosted)(foo, bar, h); } Usage: struct OneArg { char c;} struct ManyArgs { int i; float f;} void main() { auto c0 = host!ManyArgs(1,2.0,3,4.0); auto c1 = host!OneArg(1,2.0,'c'); auto c2 = host2!ManyArgs(1,2.0,3,4.0); }
Mar 11 2010