digitalmars.D - quirks of functions and delegates
- Ender KaShae (3/3) Jul 28 2007 I have two questions concerning functions and delegates (as they are so ...
- Jarrett Billingsley (21/27) Jul 28 2007 template Templ(T : U function(V), U, V...)
- Ender KaShae (2/41) Jul 31 2007
- BCS (8/31) Jul 31 2007 might this work? (I haven't tried it yet)
- Jarrett Billingsley (7/14) Jul 31 2007 shorter:
- Ender KaShae (5/44) Aug 01 2007 This doesn't quite work, when only a function type is passed I get error...
- Jarrett Billingsley (22/34) Aug 01 2007 I'm going to have to see some of your code. This works fine for me:
- Ender KaShae (37/63) Aug 02 2007 for me this outputs "Error: string expected for message not Templ"
- Jarrett Billingsley (16/42) Aug 02 2007 You must have an old compiler then. This works fine with DMD 1.020 and
I have two questions concerning functions and delegates (as they are so similar I will refer to them simply as functions from now on) 1.) can you specify a template argument to be a function and 2.) can you have arrays of functions 1.) when I try template t(type: function) I get an error, but there must be some way to specify that you need the type to be a function 2.) in an example in the docs it says that arrays of functions are invalid types in c++ and d, however i've used arrays of function pointers in c++ and it seems strange that such a type would be invalid, a function pointer is after all just a pointer
Jul 28 2007
"Ender KaShae" <astrothayne gmail.com> wrote in message news:f8ghug$5bg$1 digitalmars.com...1.) when I try template t(type: function) I get an error, but there must be some way to specify that you need the type to be a functiontemplate Templ(T : U function(V), U, V...) { } void main() { mixin Templ!(int); // fails mixin Templ!(void function(int, float)); // OK } :)2.) in an example in the docs it says that arrays of functions are invalid types in c++ and d, however i've used arrays of function pointers in c++ and it seems strange that such a type would be invalid, a function pointer is after all just a pointerThere's a slight difference. A function pointer is valid in both languages, but a function type is illegal. It's very difficult to get at a function type in D, but possible. Consider: typedef void Foo(); Foo[] f; typedef void function() Bar; Bar[] g; Notice that the first defines Foo as a function -- not function _pointer_ -- type. Foo[] f; fails. But the second defines Bar as a function pointer, and Bar[] g is fine.
Jul 28 2007
Jarrett Billingsley Wrote:"Ender KaShae" <astrothayne gmail.com> wrote in message news:f8ghug$5bg$1 digitalmars.com...I tried that, however when instantiating the template the return type and paramater tuple must be explicitly given, using a static if statement can be used to the same affect however1.) when I try template t(type: function) I get an error, but there must be some way to specify that you need the type to be a functiontemplate Templ(T : U function(V), U, V...) { } void main() { mixin Templ!(int); // fails mixin Templ!(void function(int, float)); // OK } :)2.) in an example in the docs it says that arrays of functions are invalid types in c++ and d, however i've used arrays of function pointers in c++ and it seems strange that such a type would be invalid, a function pointer is after all just a pointerThere's a slight difference. A function pointer is valid in both languages, but a function type is illegal. It's very difficult to get at a function type in D, but possible. Consider: typedef void Foo(); Foo[] f; typedef void function() Bar; Bar[] g; Notice that the first defines Foo as a function -- not function _pointer_ -- type. Foo[] f; fails. But the second defines Bar as a function pointer, and Bar[] g is fine.
Jul 31 2007
Reply to Ender,Jarrett Billingsley Wrote:might this work? (I haven't tried it yet) template T(F) { staic if(is(F R == function)) else static assert(false); }"Ender KaShae" <astrothayne gmail.com> wrote in message news:f8ghug$5bg$1 digitalmars.com...I tried that, however when instantiating the template the return type and paramater tuple must be explicitly given, using a static if statement can be used to the same affect however1.) when I try template t(type: function) I get an error, but there must be some way to specify that you need the type to be a functiontemplate Templ(T : U function(V), U, V...) { } void main() { mixin Templ!(int); // fails mixin Templ!(void function(int, float)); // OK } :)
Jul 31 2007
"BCS" <ao pathlink.com> wrote in message news:ce0a3343c58c8c9a19db144d622 news.digitalmars.com...might this work? (I haven't tried it yet) template T(F) { staic if(is(F R == function)) else static assert(false); }shorter: template T(F) { static assert(is(F == function)); }
Jul 31 2007
Jarrett Billingsley Wrote:"Ender KaShae" <astrothayne gmail.com> wrote in message news:f8ghug$5bg$1 digitalmars.com...This doesn't quite work, when only a function type is passed I get errors saying that the template was not instatiated correctly and a ton of weird errors about function pointer not implicitly casting to int's, I have no idea what that's about however when the return and paramater types are explicitly given it runs fine, though it's a little inconvienent to have to supply those twice1.) when I try template t(type: function) I get an error, but there must be some way to specify that you need the type to be a functiontemplate Templ(T : U function(V), U, V...) { } void main() { mixin Templ!(int); // fails mixin Templ!(void function(int, float)); // OK } :)so what exactly does Foo mean (without the & operator) and why would anyone want a Foo[] (whatever that means) it seems to me that Foo is a symbol, not a type. on that note, if you have a function int func(); and evaluate typeid(typeof(func)) you get the type int() which is odd since func is evaluated the same as func() so the type should just be int2.) in an example in the docs it says that arrays of functions are invalid types in c++ and d, however i've used arrays of function pointers in c++ and it seems strange that such a type would be invalid, a function pointer is after all just a pointerThere's a slight difference. A function pointer is valid in both languages, but a function type is illegal. It's very difficult to get at a function type in D, but possible. Consider: typedef void Foo(); Foo[] f; typedef void function() Bar; Bar[] g; Notice that the first defines Foo as a function -- not function _pointer_ -- type. Foo[] f; fails. But the second defines Bar as a function pointer, and Bar[] g is fine.
Aug 01 2007
"Ender KaShae" <astrothayne gmail.com> wrote in message news:f8qffl$er3$1 digitalmars.com...This doesn't quite work, when only a function type is passed I get errors saying that the template was not instatiated correctly and a ton of weird errors about function pointer not implicitly casting to int's, I have no idea what that's about however when the return and paramater types are explicitly given it runs fine, though it's a little inconvienent to have to supply those twiceI'm going to have to see some of your code. This works fine for me: template Templ(T : U function(V), U, V...) { const Templ = T.stringof; } void main() { pragma(msg, Templ!(int function(float))); pragma(msg, Templ!(void function(char[], int[char[]]))); }so what exactly does Foo mean (without the & operator) and why would anyone want a Foo[] (whatever that means) it seems to me that Foo is a symbol, not a type.Foo is a type. You can make pointers by adding an asterisk to it like any other type: Foo*. It's not a very useful type, it's just there for completeness.on that note, if you have a function int func(); and evaluate typeid(typeof(func)) you get the type int() which is odd since func is evaluated the same as func() so the type should just be intAgain, I'm going to have to see code. function int func() is an incomplete function literal. It means nothing and does not compile. However if you write "int function() func;" and then get the typeid(typeof(func)), it's "int()*" (that is a pointer to a function which takes nothing and returns an int), which makes sense because the "call a function without parens" does not apply to function _pointers_, only _functions_ (there's a use for that function type!).
Aug 01 2007
Jarrett Billingsley Wrote:I'm going to have to see some of your code. This works fine for me: template Templ(T : U function(V), U, V...) { const Templ = T.stringof; } void main() { pragma(msg, Templ!(int function(float))); pragma(msg, Templ!(void function(char[], int[char[]]))); }for me this outputs "Error: string expected for message not Templ" this is the code that I used (and failed): template Templ(T : U function(V), U, V...) { T f; U call(V v) { return f(v);} } void func(int i, float f, char[] s) { writefln(i, f, s); } void main() { alias Templ!(void function(int, float, char[])) TemplTest; TemplTest.f = &func; TemplTest.call(1, 1.0, "1"); } the error messages were: main.d(11): Error: expected 3 arguments, not 0 main.d(20): template instance main.Templ!(void(*)(int, float, char[])) error instantiating main.d(21): Error: template instance 'Templ!(void(*)(int, float, char[]))' is not a variable main.d(21): Error: no property 'f' for type 'int' main.d(21): Error: constant (Templ!(void(*)(int, float, char[]))).f is not an lvalue main.d(21): Error: cannot implicitly convert expression (& func) of type void(*)(int, float, char[]) to int main.d(22): Error: template instance 'Templ!(void(*)(int, float, char[]))' is not a variable main.d(22): Error: no property 'call' for type 'int' main.d(22): Error: function expected before (), not 1 of type intheres the code: int Foo() {return 1;} void main() { writefln(typeid(typeof(Foo))); } prints int() writefln(typeof(Foo)); gives "Error: type int() is not an expression" writefln(typeid(Foo)); gives the error: "function main.Foo is used as a type"on that note, if you have a function int func(); and evaluate typeid(typeof(func)) you get the type int() which is odd since func is evaluated the same as func() so the type should just be intAgain, I'm going to have to see code. function int func() is an incomplete function literal. It means nothing and does not compile. However if you write "int function() func;" and then get the typeid(typeof(func)), it's "int()*" (that is a pointer to a function which takes nothing and returns an int), which makes sense because the "call a function without parens" does not apply to function _pointers_, only _functions_ (there's a use for that function type!).
Aug 02 2007
"Ender KaShae" <astrothayne gmail.com> wrote in message news:f8t0t1$1m93$1 digitalmars.com...You must have an old compiler then. This works fine with DMD 1.020 and should work in 2.003 by proxy.template Templ(T : U function(V), U, V...) { const Templ = T.stringof; } void main() { pragma(msg, Templ!(int function(float))); pragma(msg, Templ!(void function(char[], int[char[]]))); }for me this outputs "Error: string expected for message not Templ"this is the code that I used (and failed): template Templ(T : U function(V), U, V...) { T f; U call(V v) { return f(v);} }I think you may have found a bug here. For some reason, T is correct, U is correct, but V ends up as an empty tuple every time. Odd.int Foo() {return 1;} void main() { writefln(typeid(typeof(Foo))); } prints int()I see what you're saying now, and it's actually not ambiguous. See, the "function call without parens" only comes into effect when symbol lookup finds that the symbol is a function type, but the destination is a different type. Then it implicitly inserts the parens and tries to do semantic analysis on it again. However, inside typeof(), there's no ambiguity; typeof(Foo) just means "the type of the symbol Foo". However, if you do something like "writefln(typeid(typeof(Foo + 1)))" _now_ the implicit function call kicks in, and you get "int".writefln(typeof(Foo)); gives "Error: type int() is not an expression"Makes sense, you can't use a type as an expression.writefln(typeid(Foo)); gives the error: "function main.Foo is used as a type"Again makes sense, as Foo refers to a function, and not a type.
Aug 02 2007