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 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 reply "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
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
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
Apr 23 2010
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 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