digitalmars.D.learn - template ref parameter
- Jack Applegame (10/10) Nov 21 2012 Why this could not compile?
- Jonathan M Davis (6/19) Nov 21 2012 ref is not part of a type. It's only a storage class, and it's only lega...
- Jack Applegame (6/6) Nov 21 2012 But sometimes ref becomes a part of type. For example "void
- bearophile (7/14) Nov 21 2012 In one case the function expects a pointer and in one case it
- Jack Applegame (2/5) Nov 21 2012 Of course. And it is mean that ref indeed is a part of type.
- Jonathan M Davis (6/12) Nov 21 2012 storage classes on function parameters affect the type of the function, ...
- Jack Applegame (1/9) Nov 21 2012 Ok. But how to pass storage class to template?
- Jonathan M Davis (7/13) Nov 21 2012 That's because ref is being used on a function parameter. That gives the...
- Jack Applegame (8/8) Nov 21 2012 How to implement functor-like objects if ref is storage class?
- Regan Heath (15/22) Nov 21 2012 Hmm.. well I got past your initial problem, but I have a new one..
- Regan Heath (7/27) Nov 21 2012 Just realised what is happening here. "f.func = " is trying to call the ...
- Regan Heath (16/45) Nov 21 2012 Or not, duh! "A..." grr.
- Jack Applegame (12/22) Nov 21 2012 I think the best way is using @property.
- Jack Applegame (22/22) Nov 21 2012 Ugly C++ like template and mixin magic solution:
- Jack Applegame (21/21) Nov 21 2012 This problem appears also in std.signals.
- Andrej Mitrovic (5/20) Nov 21 2012 Known problem, no known proposals or solutions. But there are
Why this could not compile? struct Foo(T) {} Foo!(ref int) foo; Output: Error: expression expected, not 'ref' Error: found 'int' when expecting ')' following template argument list Error: no identifier for declarator Foo!(0) Error: semicolon expected, not ')' Error: found ')' instead of statement
Nov 21 2012
On Wednesday, November 21, 2012 11:55:53 Jack Applegame wrote:Why this could not compile? struct Foo(T) {} Foo!(ref int) foo; Output: Error: expression expected, not 'ref' Error: found 'int' when expecting ')' following template argument list Error: no identifier for declarator Foo!(0) Error: semicolon expected, not ')' Error: found ')' instead of statementref is not part of a type. It's only a storage class, and it's only legal on function parameters, return types, and foreach's loop variables. It's not legal on local variables or member variables or anything of the sort. So, ref int for a template argument makes no sense whatsoever. - Jonathan M Davis
Nov 21 2012
But sometimes ref becomes a part of type. For example "void delegate(ref int)" and "void delegate(int)" are different types. Is it possible to cast from one to another safely? For example: void foo(ref int); void function(int) fp; fp = cast(typeof(fp)) foo; /// is it safe???
Nov 21 2012
Jack Applegame: A brony? :-)But sometimes ref becomes a part of type. For example "void delegate(ref int)" and "void delegate(int)" are different types. Is it possible to cast from one to another safely? For example: void foo(ref int); void function(int) fp; fp = cast(typeof(fp)) foo; /// is it safe???In one case the function expects a pointer and in one case it expects a int value. The assembly code of the two functions is different and does different things. Bye, bearophile
Nov 21 2012
On Wednesday, 21 November 2012 at 12:05:23 UTC, bearophile wrote:In one case the function expects a pointer and in one case it expects a int value. The assembly code of the two functions is different and does different things.Of course. And it is mean that ref indeed is a part of type.
Nov 21 2012
On Wednesday, November 21, 2012 13:09:05 Jack Applegame wrote:On Wednesday, 21 November 2012 at 12:05:23 UTC, bearophile wrote:storage classes on function parameters affect the type of the function, but they do not affect the type of the parameter. If a function has a parameter named foo, then typeof(foo) is going to be the same whether ref is on it or not. - Jonathan M DavisIn one case the function expects a pointer and in one case it expects a int value. The assembly code of the two functions is different and does different things.Of course. And it is mean that ref indeed is a part of type.
Nov 21 2012
storage classes on function parameters affect the type of the function, but they do not affect the type of the parameter. If a function has a parameter named foo, then typeof(foo) is going to be the same whether ref is on it or not. - Jonathan M DavisOk. But how to pass storage class to template?
Nov 21 2012
On Wednesday, November 21, 2012 12:57:57 Jack Applegame wrote:But sometimes ref becomes a part of type. For example "void delegate(ref int)" and "void delegate(int)" are different types. Is it possible to cast from one to another safely? For example:That's because ref is being used on a function parameter. That gives the function a different type, but you can't just use ref int by itself. As I said, it's only applicable to function parameters, return types, and foreach loop variables.void foo(ref int); void function(int) fp; fp = cast(typeof(fp)) foo; /// is it safe???No, it's not safe. - Jonathan M Davis
Nov 21 2012
How to implement functor-like objects if ref is storage class? void foo(ref int a) { a--; } struct functor(A...) { void function(A) functor; } functor!int f; // functor!(ref int) - wrong f.functor = &foo; // Error: cannot implicitly convert expression (& foo) of type void function(ref int a) to void function(int)
Nov 21 2012
On Wed, 21 Nov 2012 12:02:45 -0000, Jack Applegame <japplegame gmail.com> wrote:void foo(ref int a) { a--; } struct functor(A...) { void function(A) functor; } functor!int f; // functor!(ref int) - wrong f.functor = &foo; // Error: cannot implicitly convert expression (& foo) of type void function(ref int a) to void function(int)Hmm.. well I got past your initial problem, but I have a new one.. alias void function(ref int) funcType; void foo(ref int a) { a--; } struct functor(A...) { A func; } void main() { functor!funcType f; f.func = &foo; //Error: f.func is not an lvalue } -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Nov 21 2012
On Wed, 21 Nov 2012 12:30:08 -0000, Regan Heath <regan netmail.co.nz> wrote:On Wed, 21 Nov 2012 12:02:45 -0000, Jack Applegame <japplegame gmail.com> wrote:Just realised what is happening here. "f.func = " is trying to call the function, and assign &foo to the "void" result. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/void foo(ref int a) { a--; } struct functor(A...) { void function(A) functor; } functor!int f; // functor!(ref int) - wrong f.functor = &foo; // Error: cannot implicitly convert expression (& foo) of type void function(ref int a) to void function(int)Hmm.. well I got past your initial problem, but I have a new one.. alias void function(ref int) funcType; void foo(ref int a) { a--; } struct functor(A...) { A func; } void main() { functor!funcType f; f.func = &foo; //Error: f.func is not an lvalue }
Nov 21 2012
On Wed, 21 Nov 2012 12:32:24 -0000, Regan Heath <regan netmail.co.nz> wrote:On Wed, 21 Nov 2012 12:30:08 -0000, Regan Heath <regan netmail.co.nz> wrote:Or not, duh! "A..." grr. alias void function(ref int) funcType; void foo(ref int a) { a--; } struct functor(A...) { A[0] func; } void main() { functor!funcType f; f.func = &foo; } R -- Using Opera's revolutionary email client: http://www.opera.com/mail/On Wed, 21 Nov 2012 12:02:45 -0000, Jack Applegame <japplegame gmail.com> wrote:Just realised what is happening here. "f.func = " is trying to call the function, and assign &foo to the "void" result.void foo(ref int a) { a--; } struct functor(A...) { void function(A) functor; } functor!int f; // functor!(ref int) - wrong f.functor = &foo; // Error: cannot implicitly convert expression (& foo) of type void function(ref int a) to void function(int)Hmm.. well I got past your initial problem, but I have a new one.. alias void function(ref int) funcType; void foo(ref int a) { a--; } struct functor(A...) { A func; } void main() { functor!funcType f; f.func = &foo; //Error: f.func is not an lvalue }
Nov 21 2012
alias void function(ref int) funcType; void foo(ref int a) { a--; } struct functor(A...) { A[0] func; } void main() { functor!funcType f; f.func = &foo; }I think the best way is using property. alias void function(ref int) funcType; void foo(ref int a) { a--; } struct functor(A...) { property void func(A fp) { m_func = fp; } A m_func; } void main() { functor!funcType f; f.func = &foo; }
Nov 21 2012
Ugly C++ like template and mixin magic solution: struct r(T){ alias T type;} template str(alias A) if(is(A == r!(A.type))) { const char[] str = "ref " ~ A.type.stringof; } template str(T) { const char[] str = T.stringof; } template str(T, A...) { const char[] str = str!T ~ ", " ~ str!A; } struct functor(A...) { void opAssign(C)(C callable) { m_fp = callable; } void opCall(R...)(auto ref R r) { m_fp(r); } private { mixin("void function(" ~ str!A ~ ") m_fp;"); } } void foo(ref int a, int b) { a += b; } void main() { functor!(r!int, int) f; f = &foo; int a = 1, b = 2; f(a, b); assert(a == 3); }
Nov 21 2012
This problem appears also in std.signals. There is no possibility to use functions with ref parameters as signal handler. import std.signals; class Foo { mixin Signal!(int); } class Bar { void handler(ref int a) {} } void main() { Foo foo = new Foo; Bar bar = new Bar; foo.connect(&bar.handler); } outputs: Error: function signals.Foo.Signal!(int).connect (void delegate(int) slot) is not callable using argument types (void delegate(ref int a))| Error: cannot implicitly convert expression (&bar.handler) of type void delegate(ref int a) to void delegate(int)
Nov 21 2012
On 11/21/12, Jack Applegame <japplegame gmail.com> wrote:This problem appears also in std.signals. There is no possibility to use functions with ref parameters as signal handler. import std.signals; class Foo { mixin Signal!(int); } class Bar { void handler(ref int a) {} } void main() { Foo foo = new Foo; Bar bar = new Bar; foo.connect(&bar.handler); }Known problem, no known proposals or solutions. But there are workarounds, e.g. if you're writing your own signals implementation you could use a function type instead of a lone type, e.g.: mixin Signal!(void function(ref int));
Nov 21 2012