www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Anyone know what's going on here? (variable with an instantiated

reply Gareth Charnock <gareth oerc.ox.ac.uk> writes:
Is this a bug, or am I being dense? I've tried it this on 2.036,2.042 
and 2.043 and on each the compiler produces errors. Searched bugzilla 
for "template and instantiated" and "template and instantiate"

struct A(uint N)  {
}
void unary_op(uint N)(A!(N)) {
}
void main() {
     A!(3) a3;

     pragma(msg,typeof(a3)); //prints A!(3), so a3 is not void, dammit

     unary_op!3(A);// Error: cannot implicitly convert expression
                   // (A(uint N)) of type void to A!(N)
     unary_op(A);  // Error: template template.unary_op(uint N) does not 

                   // match any function template declaration
                   // Error: template template.unary_op(uint N) cannot
                   // deduce template function from argument types
                   // !()(void)   <== what?
}
Apr 23 2010
next sibling parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Gareth Charnock wrote:
 Is this a bug, or am I being dense? I've tried it this on 2.036,2.042 
 and 2.043 and on each the compiler produces errors. Searched bugzilla 
 for "template and instantiated" and "template and instantiate"
 
 struct A(uint N)  {
 }
 void unary_op(uint N)(A!(N)) {
 }
 void main() {
     A!(3) a3;
 
     pragma(msg,typeof(a3)); //prints A!(3), so a3 is not void, dammit
 
     unary_op!3(A);// Error: cannot implicitly convert expression
                   // (A(uint N)) of type void to A!(N)
     unary_op(A);  // Error: template template.unary_op(uint N) does not
                   // match any function template declaration
                   // Error: template template.unary_op(uint N) cannot
                   // deduce template function from argument types
                   // !()(void)   <== what?
 }

You are trying to call unary_op on the template A. Try this instead: unary_op!3(a3); unary_op(a3); -Lars
Apr 23 2010
parent Gareth Charnock <gareth oerc.ox.ac.uk> writes:
...er... ...
I think I'll just put on the dunce hat and stand in the corner then.

This is why, as someone with dyslexia, I like statically typed 
languages. I hate finding out about these errors at runtime.

Lars T. Kyllingstad wrote:
 Gareth Charnock wrote:
 Is this a bug, or am I being dense? I've tried it this on 2.036,2.042 
 and 2.043 and on each the compiler produces errors. Searched bugzilla 
 for "template and instantiated" and "template and instantiate"

 struct A(uint N)  {
 }
 void unary_op(uint N)(A!(N)) {
 }
 void main() {
     A!(3) a3;

     pragma(msg,typeof(a3)); //prints A!(3), so a3 is not void, dammit

     unary_op!3(A);// Error: cannot implicitly convert expression
                   // (A(uint N)) of type void to A!(N)
     unary_op(A);  // Error: template template.unary_op(uint N) does not
                   // match any function template declaration
                   // Error: template template.unary_op(uint N) cannot
                   // deduce template function from argument types
                   // !()(void)   <== what?
 }

You are trying to call unary_op on the template A. Try this instead: unary_op!3(a3); unary_op(a3); -Lars

Apr 23 2010
prev sibling next sibling parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 23 Apr 2010 10:25:35 -0300, Gareth Charnock <gareth oerc.ox.ac.uk>  
wrote:
 Is this a bug, or am I being dense? I've tried it this on 2.036,2.042  
 and 2.043 and on each the compiler produces errors. Searched bugzilla  
 for "template and instantiated" and "template and instantiate"

 struct A(uint N)  {
 }
 void unary_op(uint N)(A!(N)) {
 }
 void main() {
      A!(3) a3;

      pragma(msg,typeof(a3)); //prints A!(3), so a3 is not void, dammit

      unary_op!3(A);// Error: cannot implicitly convert expression
                    // (A(uint N)) of type void to A!(N)
      unary_op(A);  // Error: template template.unary_op(uint N) does not  
                    // match any function template declaration
                    // Error: template template.unary_op(uint N) cannot
                    // deduce template function from argument types
                    // !()(void)   <== what?
 }

Well, first, let's make this valid D code: struct A(uint N) {} void unary_op(uint N)(A!N value) {} void main(string[] args) { A!(3) a3; pragma(msg,typeof(a3)); unary_op!3(a3); unary_op(a3); } But that still doesn't compile. It looks like you're running across a variant of bug 2257 (http://d.puremagic.com/issues/show_bug.cgi?id=2257). Please vote it up.
Apr 23 2010
next sibling parent Gareth Charnock <gareth oerc.ox.ac.uk> writes:
Thanks!

Robert Jacques wrote:
 On Fri, 23 Apr 2010 10:25:35 -0300, Gareth Charnock 
 <gareth oerc.ox.ac.uk> wrote:
 Is this a bug, or am I being dense? I've tried it this on 2.036,2.042 
 and 2.043 and on each the compiler produces errors. Searched bugzilla 
 for "template and instantiated" and "template and instantiate"

 struct A(uint N)  {
 }
 void unary_op(uint N)(A!(N)) {
 }
 void main() {
      A!(3) a3;

      pragma(msg,typeof(a3)); //prints A!(3), so a3 is not void, dammit

      unary_op!3(A);// Error: cannot implicitly convert expression
                    // (A(uint N)) of type void to A!(N)
      unary_op(A);  // Error: template template.unary_op(uint N) does 
 not                    // match any function template declaration
                    // Error: template template.unary_op(uint N) cannot
                    // deduce template function from argument types
                    // !()(void)   <== what?
 }

Well, first, let's make this valid D code: struct A(uint N) {} void unary_op(uint N)(A!N value) {} void main(string[] args) { A!(3) a3; pragma(msg,typeof(a3)); unary_op!3(a3); unary_op(a3); } But that still doesn't compile. It looks like you're running across a variant of bug 2257 (http://d.puremagic.com/issues/show_bug.cgi?id=2257). Please vote it up.

Apr 23 2010
prev sibling parent Gareth Charnock <gareth.tpc gmail.com> writes:
Just got a chance to test the isInstanceOf template and it does (after 
some fiddling) provide a workaround for this bug. Thanks.

Philippe Sigaud wrote:
 On Fri, Apr 23, 2010 at 14:57, Robert Jacques <sandford jhu.edu 
 <mailto:sandford jhu.edu>> wrote:
 
     PS. You can get things like this to work using template constraints.
 
     For example, here's a horrible hack:
     void unary_op(T)(T value)
     if(T.stringof[0..3] == "A!(" && T.stringof[$-1..$] == ")"  ){}
 
 
 Maybe a bit less hacky (?) using an is expression:
 
 void unary_op(T)(T value) if (is(T TT == A!N, uint N)) {}
 
 
 N does not exist inside the function, though. For that, you'd have to 
 recreate it with a static if:
 
 void unary_op(T)(T value) if (is(T TT == A!N, uint N))
 {
     static if (is(T TT == A!N, uint N)) // read this as "if T is a type 
 like A!N, for some uint N"
         writeln(N);
 }
 
 
 I have a template that may be useful there:
 
 /**
 isInstanceOf!(Type, templateName) is true iff Type is an instantiation 
 (is that the right term?) of templateName.
 */
 template isInstanceOf(T, alias templ)
 {
     static if (T.stringof.length >= __traits(identifier, templ).length 
 && T.stringof[0..__traits(identifier, templ).length] == 
 __traits(identifier, templ))
         enum bool isInstanceOf = true;
     else
         enum bool isInstanceOf = false;
 }
 
 Example:
 
 void unary_op2(T)(T value) if (isInstanceOf!(T, A))
 {
 // T is an A!(someParam)
 }
 
 If you want to extract the 'someParam' part, it's doable by using a CT 
 function that extracts what's between the first '(' and the 
 corresponding ')'. I think I have somewhere a template that alias itself 
 to the corresponding typetuple:
 
 TemplateParametersTypeTuple!(Temp!(int, double, char[]))  =>  
 TypeTuple!(int,double, char[])
 
 Is anyone interested by this one?
 
 Philippe
 
 
 
 

Apr 24 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 23 Apr 2010 09:43:10 -0300, Robert Jacques <sandford jhu.edu>  
wrote:

 On Fri, 23 Apr 2010 10:25:35 -0300, Gareth Charnock  
 <gareth oerc.ox.ac.uk> wrote:
 Is this a bug, or am I being dense? I've tried it this on 2.036,2.042  
 and 2.043 and on each the compiler produces errors. Searched bugzilla  
 for "template and instantiated" and "template and instantiate"

 struct A(uint N)  {
 }
 void unary_op(uint N)(A!(N)) {
 }
 void main() {
      A!(3) a3;

      pragma(msg,typeof(a3)); //prints A!(3), so a3 is not void, dammit

      unary_op!3(A);// Error: cannot implicitly convert expression
                    // (A(uint N)) of type void to A!(N)
      unary_op(A);  // Error: template template.unary_op(uint N) does  
 not                    // match any function template declaration
                    // Error: template template.unary_op(uint N) cannot
                    // deduce template function from argument types
                    // !()(void)   <== what?
 }

Well, first, let's make this valid D code: struct A(uint N) {} void unary_op(uint N)(A!N value) {} void main(string[] args) { A!(3) a3; pragma(msg,typeof(a3)); unary_op!3(a3); unary_op(a3); } But that still doesn't compile. It looks like you're running across a variant of bug 2257 (http://d.puremagic.com/issues/show_bug.cgi?id=2257). Please vote it up.

PS. You can get things like this to work using template constraints. For example, here's a horrible hack: void unary_op(T)(T value) if(T.stringof[0..3] == "A!(" && T.stringof[$-1..$] == ")" ){}
Apr 23 2010
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--0015175d67ae10f0220484ed9d82
Content-Type: text/plain; charset=ISO-8859-1

On Fri, Apr 23, 2010 at 14:57, Robert Jacques <sandford jhu.edu> wrote:

 PS. You can get things like this to work using template constraints.

 For example, here's a horrible hack:
 void unary_op(T)(T value)
 if(T.stringof[0..3] == "A!(" && T.stringof[$-1..$] == ")"  ){}

Maybe a bit less hacky (?) using an is expression: void unary_op(T)(T value) if (is(T TT == A!N, uint N)) {} N does not exist inside the function, though. For that, you'd have to recreate it with a static if: void unary_op(T)(T value) if (is(T TT == A!N, uint N)) { static if (is(T TT == A!N, uint N)) // read this as "if T is a type like A!N, for some uint N" writeln(N); } I have a template that may be useful there: /** isInstanceOf!(Type, templateName) is true iff Type is an instantiation (is that the right term?) of templateName. */ template isInstanceOf(T, alias templ) { static if (T.stringof.length >= __traits(identifier, templ).length && T.stringof[0..__traits(identifier, templ).length] == __traits(identifier, templ)) enum bool isInstanceOf = true; else enum bool isInstanceOf = false; } Example: void unary_op2(T)(T value) if (isInstanceOf!(T, A)) { // T is an A!(someParam) } If you want to extract the 'someParam' part, it's doable by using a CT function that extracts what's between the first '(' and the corresponding ')'. I think I have somewhere a template that alias itself to the corresponding typetuple: TemplateParametersTypeTuple!(Temp!(int, double, char[])) => TypeTuple!(int,double, char[]) Is anyone interested by this one? Philippe --0015175d67ae10f0220484ed9d82 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On Fri, Apr 23, 2010 at 14:57, Robert Jacques <s= pan dir=3D"ltr">&lt;<a href=3D"mailto:sandford jhu.edu">sandford jhu.edu</a=
&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0=

1ex;"> <div><div></div>PS. You can get things like this to work using template con= straints.<br></div> <br> For example, here&#39;s a horrible hack:<br> void unary_op(T)(T value)<br> if(T.stringof[0..3] =3D=3D &quot;A!(&quot; &amp;&amp; T.stringof[$-1..$] = =3D=3D &quot;)&quot; =A0){}<br> </blockquote></div><br>Maybe a bit less hacky (?) using an is expression:<b= r><br>void unary_op(T)(T value) if (is(T TT =3D=3D A!N, uint N)) {}<br><br>= <br>N does not exist inside the function, though. For that, you&#39;d have = to recreate it with a static if:<br> <br>void unary_op(T)(T value) if (is(T TT =3D=3D A!N, uint N)) <br>{<br>=A0= =A0=A0 static if (is(T TT =3D=3D A!N, uint N)) // read this as &quot;if T i= s a type like A!N, for some uint N&quot;<br>=A0=A0=A0=A0=A0=A0=A0 writeln(N= );<br>}<br><br><br>I have a template that may be useful there:<br> <br>/**<br>isInstanceOf!(Type, templateName) is true iff Type is an instant= iation (is that the right term?) of templateName.<br>*/<br>template isInsta= nceOf(T, alias templ)<br>{<br>=A0=A0=A0 static if (T.stringof.length &gt;= =3D __traits(identifier, templ).length &amp;&amp; T.stringof[0..__traits(id= entifier, templ).length] =3D=3D __traits(identifier, templ))<br> =A0=A0=A0=A0=A0=A0=A0 enum bool isInstanceOf =3D true;<br>=A0=A0=A0 else<br=
=A0=A0=A0=A0=A0=A0=A0 enum bool isInstanceOf =3D false;<br>}<br><br>Exampl=

is an A!(someParam)<br>}<br><br>If you want to extract the &#39;someParam&= #39; part, it&#39;s doable by using a CT function that extracts what&#39;s = between the first &#39;(&#39; and the corresponding &#39;)&#39;. I think I = have somewhere a template that alias itself to the corresponding typetuple:= <br> <br>TemplateParametersTypeTuple!(Temp!(int, double, char[]))=A0 =3D&gt;=A0 = TypeTuple!(int,double, char[])<br><br>Is anyone interested by this one?<br>= <br>Philippe<br><br><br><br><br> --0015175d67ae10f0220484ed9d82--
Apr 23 2010