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
next sibling parent 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
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--0003255540728b2e0104818c5253
Content-Type: text/plain; charset=ISO-8859-1

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); } --0003255540728b2e0104818c5253 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On Thu, Mar 11, 2010 at 21:03, BCS <span dir=3D"= ltr">&lt;<a href=3D"mailto:none anon.com">none anon.com</a>&gt;</span> wrot= e:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex;= border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"> <br><div class=3D"im"><blockquote class=3D"gmail_quote" style=3D"margin: 0p= t 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1= ex;"> <br> i.e.<br> <br> static C create(Args...)(int foo, float bar, Args args)<br> {<br> auto c =3D new C(foo, bar);<br> c.t =3D T(args);<br> return c;<br> }<br> </blockquote> <br></div>What about a static function instead of a constructor?<br></block= quote><div><br>Two variations on the same theme:<br><br>storing (Args...) a= s a template parameter in the host class<br><br>class Host(Hosted, Args...)= {<br> =A0=A0=A0 Hosted t;<br>=A0=A0=A0 this(int foo, float bar, Args args)<br>=A0= =A0=A0 {<br>=A0=A0=A0=A0 t =3D Hosted(args);<br>=A0=A0=A0 }<br>}<br><br>and= using a helper function to do the type extraction:<br><br>Host!(Hosted, Ar= gs) host(Hosted, Args...)(int foo, float bar, Args args)<br> {<br>=A0=A0=A0 return new Host!(Hosted, Args)(foo, bar, args);<br>}<br><br>= Or, give the host a constructor taking a Hosted already created:<br><br><br=
class Host2(Hosted) {<br>=A0=A0=A0 Hosted h;<br>=A0=A0=A0 this(int foo, fl=

=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 this.h =3D h;<br>=A0=A0=A0 }<br>}<br><= br>Host2!(Hosted) host2(Hosted, Args...)(int foo, float bar, Args args)<br>= {<br>=A0=A0=A0 auto h =3D Hosted(args);<br>=A0=A0=A0 return new Host2!(Host= ed)(foo, bar, h);<br>}<br><br>Usage:<br> <br>struct OneArg { char c;}<br><br>struct ManyArgs {=A0int i; float f;}<br=
<br>void main()<br>{<br>=A0=A0=A0 auto c0 =3D host!ManyArgs(1,2.0,3,4.0);<=

=3D host2!ManyArgs(1,2.0,3,4.0);<br> =A0}</div></div> --0003255540728b2e0104818c5253--
Mar 11 2010