digitalmars.D - Anyone know what's going on here? (variable with an instantiated
- Gareth Charnock (18/18) Apr 23 2010 Is this a bug, or am I being dense? I've tried it this on 2.036,2.042
- Lars T. Kyllingstad (5/26) Apr 23 2010 You are trying to call unary_op on the template A. Try this instead:
- Gareth Charnock (5/35) Apr 23 2010 ...er... ...
- Robert Jacques (14/32) Apr 23 2010 Well, first, let's make this valid D code:
- Robert Jacques (6/41) Apr 23 2010 PS. You can get things like this to work using template constraints.
- Philippe Sigaud (38/42) Apr 23 2010 Maybe a bit less hacky (?) using an is expression:
- Gareth Charnock (3/67) Apr 24 2010 Just got a chance to test the isInstanceOf template and it does (after
- Gareth Charnock (2/46) Apr 23 2010
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
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
...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
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
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: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..$] == ")" ){}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
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
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
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