digitalmars.D - Function template parameter inference from class template argument
- Justin Johansson (38/38) Sep 23 2009 D1.0
- Jarrett Billingsley (24/60) Sep 23 2009 ass template of the same type parameter, T, as an argument, then typical...
- Justin Johansson (27/65) Sep 23 2009 Wow Jarret!!! So many words on my part to explain what I wanted and you...
- Jarrett Billingsley (24/47) Sep 23 2009 u came up with this just so, so coolly concise solution. =A0It doesn't e...
- Justin Johansson (4/25) Sep 23 2009 Thanks again. I tried that before posting and it didn't work. Checked ...
D1.0 If you have a function template of one type parameter, T, that takes a class template of the same type parameter, T, as an argument, then typical template usage scenario goes like this: /* Class template definition */ class Foo(T) { } /* Function template definition */ void bar(T)( Foo!(T) arg) { // ... } /* Instantiation usage */ main() { auto foo = new Foo!(float)(); /* line A */ bar!(float)( foo); /* line B */ } Now since in the main function the compiler knows that T is float at line A, it occurs to me that code noise could be reduced a bit if the compiler could somehow deduce at line B that the function template parameter, T, is float without it having to be explicitly written. The instantiation usage would now look like this: /* Less-noisy instantiation usage */ main() { auto foo = new Foo!(float)(); /* line A */ bar( foo); /* line B */ } The only problem is how then to write the function template definition so that T can be defaulted to the class parameter, T, that accompanies Foo. One idea I had, which of course doesn't work, is to define the function template's argument with the auto keyword and then somehow figure out T from the argument like so: /* Function template definition */ void bar(T = typeof( arg))( auto arg) { // ... } Since I'm getting used to finding cool features in D that always lets you do stuff you never dreamed of, and since I have a lot of template instantiation code, it would be really neat to be able to reduce the noise a bit as outlined above. Any ideas anybody? (Note D1.0) Perhaps this is a no brainer and I just goofed up but have given up after a spending way too much time on it thus far. Thanks all. Justin Johansson
Sep 23 2009
On Wed, Sep 23, 2009 at 9:55 AM, Justin Johansson <procode adam-dott-com.au> wrote:D1.0 If you have a function template of one type parameter, T, that takes a cl=ass template of the same type parameter, T, as an argument, then typical te= mplate usage scenario goes like this:=A0 =A0 =A0 =A0/* Class template definition */ =A0 =A0 =A0 =A0class Foo(T) { =A0 =A0 =A0 =A0} =A0 =A0 =A0 =A0/* Function template definition */ =A0 =A0 =A0 =A0void bar(T)( Foo!(T) arg) { =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0// ... =A0 =A0 =A0 =A0} =A0 =A0 =A0 =A0/* Instantiation usage */ =A0 =A0 =A0 =A0main() =A0 =A0 =A0 =A0{ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0auto foo =3D new Foo!(float)(); =A0 /* lin=e A */=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0bar!(float)( foo); =A0 =A0 =A0 =A0 =A0 =A0==A0 =A0 =A0 =A0 =A0/* line B */=A0 =A0 =A0 =A0} Now since in the main function the compiler knows that T is float at line=A, it occurs to me that code noise could be reduced a bit if the compiler = could somehow deduce at line B that the function template parameter, T, is = float without it having to be explicitly written.The instantiation usage would now look like this: /* Less-noisy instantiation usage */ main() { =A0 =A0 =A0 =A0auto foo =3D new Foo!(float)(); =A0 /* line A */ =A0 =A0 =A0 =A0bar( foo); =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0==A0 =A0 =A0 =A0 =A0 =A0 =A0/* line B */} The only problem is how then to write the function template definition so=that T can be defaulted to the class parameter, T, that accompanies Foo.One idea I had, which of course doesn't work, is to define the function t=emplate's argument with the auto keyword and then somehow figure out T from= the argument like so:=A0 =A0 =A0 =A0/* Function template definition */ =A0 =A0 =A0 =A0void bar(T =3D typeof( arg))( auto arg) { =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0// ... =A0 =A0 =A0 =A0} Since I'm getting used to finding cool features in D that always lets you=do stuff you never dreamed of,and since I have a lot of template instantiation code, it would be really neat to be able to reduce the noise a bit as outlined =above.Any ideas anybody? (Note D1.0) Perhaps this is a no brainer and I just goofed up but have given up after=a spending way too much time on it thus far.Thanks all. Justin Johanssonclass Foo(T) {} void bar(T : Foo!(U), U)(T t) {} void main() { auto foo =3D new Foo!(float)(); bar(foo); } :)
Sep 23 2009
Jarrett Billingsley Wrote:If you have a function template of one type parameter, T, that takes a class template of the same type parameter, T, as an argument, then typical template usage scenario goes like this: /* Class template definition */ class Foo(T) { } /* Function template definition */ void bar(T)( Foo!(T) arg) { // ... } /* Instantiation usage */ main() { auto foo = new Foo!(float)(); /* line A */ bar!(float)( foo); /* line B */ } /* Less-noisy instantiation usage */ main() { auto foo = new Foo!(float)(); /* line A */ bar( foo); /* line B */ }class Foo(T) {} void bar(T : Foo!(U), U)(T t) {} void main() { auto foo = new Foo!(float)(); bar(foo); } :)Wow Jarret!!! So many words on my part to explain what I wanted and you came up with this just so, so coolly concise solution. It doesn't exactly look like a textbook solution so me thinks I can forgive myself for not figuring it out. (hey only 3 weeks into D now). I don't know if it would be pushing my luck or not, but is your concept generalizable to more parameters. In particular I want to be able to extend this so than bar() can return a generic type. So now I have this: class Foo(T) {} T2 bar(T : Foo!(U), U)(T t) { T2 x = ... return x; } void main() { auto foo = new Foo!(float)(); auto chu = bar!(double, float)( foo); // type of chu is double } and by analogy with the first problem I would like to instantiate like so: void main() { auto foo = new Foo!(float)(); auto chu = bar!(double)( foo); // be nice if float could be deduced from foo parameter // type of chu is double } Thanks muchly, -- Justin
Sep 23 2009
On Wed, Sep 23, 2009 at 6:17 PM, Justin Johansson <procode adam-dott-com.au> wrote:Wow Jarret!!! =A0So many words on my part to explain what I wanted and yo=u came up with this just so, so coolly concise solution. =A0It doesn't exac= tly look like a textbook solution so me thinks I can forgive myself for not= figuring it out. (hey only 3 weeks into D now).I don't know if it would be pushing my luck or not, but is your concept g=eneralizable to more parameters. =A0In particular I want to be able to exte= nd this so than bar() can return a generic type.So now I have this: class Foo(T) {} T2 bar(T : Foo!(U), U)(T t) { =A0T2 x =3D ... =A0return x; } void main() { =A0 =A0 =A0 =A0auto foo =3D new Foo!(float)(); =A0 =A0 =A0 =A0auto chu =3D bar!(double, float)( foo); =A0 =A0 =A0 // type of chu is double } and by analogy with the first problem I would like to instantiate like so=:void main() { =A0 =A0 =A0 =A0auto foo =3D new Foo!(float)(); =A0 =A0 =A0 =A0auto chu =3D bar!(double)( foo); =A0 =A0// be nice if floa=t could be deduced from foo parameter=A0 =A0 =A0 // type of chu is double }class Foo(T) {} R bar(R, T : Foo!(U), U)(T t) { R r; return r; } void main() { auto foo =3D new Foo!(float)(); auto chu =3D bar!(double)(foo); pragma(msg, typeof(chu).stringof); } Make sure you have a newer compiler, though, as partial template specialization with IFTI was only introduced in DMD 1.038.
Sep 23 2009
Jarrett Billingsley Wrote:Thanks again. I tried that before posting and it didn't work. Checked my DMD version .. missed out by 0.001 .. I had DMD 1.037. Upgraded just now to DMD 1.047 and your solution rocks yet again :-) <JJ/>I don't know if it would be pushing my luck or not, but is your concept generalizable to more parameters. In particular I want to be able to extend this so than bar() can return a generic type.class Foo(T) {} R bar(R, T : Foo!(U), U)(T t) { R r; return r; } void main() { auto foo = new Foo!(float)(); auto chu = bar!(double)(foo); pragma(msg, typeof(chu).stringof); } Make sure you have a newer compiler, though, as partial template specialization with IFTI was only introduced in DMD 1.038.
Sep 23 2009